Why doesn't this build

I get an error

argument of this type const char is incompatible with parameter
main.cpp

#include <iostream>
#include <cstdlib>

using namespace std;

#include "menu.h"

void func1();
void func2();
void func3();
void Exit();

int main()
{
Menu m;
m.addMenu("1. Function1 ", func1);
m.addMenu("2. Function2 ", func2);
m.addMenu("3. Function3 ", func3);
m.addMenu("4. Exit ", Exit);

m.runMenu();
}
void func1()
{
char c;
cout << "hello from function 1";
cin >> c;
}
void func2()
{
char c;
cout << "hello from function 2";
cin >> c;
}
void func3()
{
char c;
cout << "hello from function 3";
cin >> c ;
}
void Exit()
{
cout << "GoodBye" << endl;
exit(0);
}
menu.cpp

#include <iostream>
#include <cstdlib>

using namespace std;

#include "menu.h"
#include <conio.h>

Menu::Menu()
: count(0)
{

}
void Menu::addMenu(char* Description, void (*f)(void))
{
if (count < MAXCOUNT)
{
this->mi[count].func = f;
strcpy_s(this->mi[count].decript, Description);
count++;
}
}
void Menu::runMenu()
{
for (;;)
{
system("CLS");
for (int i = 0; i < count; i++)
{
cout << this->mi[i].decript << endl;
}
runSelection();
}
}
void Menu::runSelection()
{
int select;

cin >> select;
if (select <= count)
this->mi[select - 1].func();
}
void waitKey()
{

cout << "Press any key to continue" << endl;
while (!_kbhit()); // kbhit is depricated. use _kbhit

fflush(stdin);
}

menu.h

#ifndef MENU
#define MENU

const int MAXCOUNT = 20;
struct menuItem
{
void (*func) ();
char decript[50];

};
class Menu
{
private:
menuItem mi[MAXCOUNT];
int count;
void runSelection();
public:
Menu();
void addMenu(char* Description, void (*f)());
void runMenu();
};
#endif#pragma once
1. You forgot the code tags.
http://www.cplusplus.com/articles/jEywvCM9/

2. Why aren't you using std::string anyway?

3. If you must use char pointer, then at least make them const.
> void addMenu(const char* Description, void (*f)());

4. strcpy_s(this->mi[count].decript, Description);
It's only safe if you know how to use it.
> https://en.cppreference.com/w/c/string/byte/strcpy
strcpy_s has THREE parameters.
Did you really get no warning when you compiled this line?

5. std::bind gives you much more safety, and much more flexibility than C-style naked function pointers.
https://en.cppreference.com/w/cpp/utility/functional/bind
Ok I tried to fix it but it still does not build
I get 'Menu::addMenu': function does not take 2 arguments
syntax error: identifier 'string'
missing type specifier - int assumed. C++ does not support default-int Menu.h-12
Variable Menu::mi is uninitialized menu.cpp line 8

Menu.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <string>
#ifndef MENU
#define MENU
const int MAXCOUNT = 20;
struct menuItem
{
	void (*func) ();
	string descript;
};
class Menu
{
private:
	menuItem mi[MAXCOUNT];
	int count;
	void runSelection();
public:
	Menu();
	void addMenu(string Description, void(*f) ());
	void runMenu();
};

#endif 

Menu.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <cstdlib>
#include "Menu.h"

using namespace std;
Menu::Menu()
	:count(0)
{

}
void Menu::addMenu(string Description, void(*f) (void))
{
	if (count < MAXCOUNT)
	{
		this->mi[count].func = f;
		this->mi[count].descript = Description;
		count++;
	}
}

void Menu::runMenu()
{
	for (;;)
	{
		system("CLS");
		for (int i = 0; i < count; i++)
		{
			cout << this->mi[i].descript << endl;
		}
		runSelection();
	}
}

void Menu::runSelection()
{
	int select;
	cin >> select;
	if (select <= count)
		this->mi[select - 1].func();
}

Main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <cstdlib>
#include <conio.h>
#include "Menu.h"

using namespace std;

void func1();
void func2();
void func3();
void Exit();
void waitKey();

int main()
{
	Menu m;
	m.addMenu("1. Function1", func1);
	m.addMenu("2. Function2", func2);
	m.addMenu("3. Function3", func3);
	m.addMenu("4. Exit", Exit);
	m.runMenu();
}
void func1()
{
	string c;
	cout << "Hello from function 1.";
	cin >> c;
}
void func2()
{
	string c;
	cout << "Hello from function 2.";
	cin >> c;
}
void func3()
{
	string c;
	cout << "Hello from function 3.";
	cin >> c;
}
void Exit()
{
	cout << "Goodbye." << endl;
	exit(0);
}
void waitKey()
{
	cout << "Press any key to continue." << endl;
	while (!_kbhit());
	fflush(stdin);
}
Last edited on
Errors that I get when trying to build OP's project (after stripping out the Windows-specific stuff):
Buildtest/Menu.h:8:2: error: unknown type name 'string'; did you mean 'std::string'?
        string descript;
        ^~~~~~
        std::string
Buildtest/Menu.h:18:15: error: unknown type name 'string'; did you mean 'std::string'?
        void addMenu(string Description, void(*f) ());
                     ^~~~~~
                     std::string


-Albatross
Try this menu.h
Note the use of std::
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <string>
#ifndef MENU
#define MENU
const int MAXCOUNT = 20;
struct menuItem
{
	void (*func) ();
	std::string descript;
};
class Menu
{
private:
	menuItem mi[MAXCOUNT];
	int count;
	void runSelection();
public:
	Menu();
	void addMenu(std::string Description, void(*f) ());
	void runMenu();
};

#endif  


Do NOT try to make your life "easy" by adding using namespace std; to your header files.
It will only make your life difficult later on.

thanks salem, that fixed it
Topic archived. No new replies allowed.