Hej
Chcę przekazać jako parametr do konstruktora klasy menu_item
wskaźnik na funkcję nie przyjmującą argumentów, która nie będzie nic zwracać. Funkcja ma być wywoływana w metodzie loop
klasy menu
. W wektorze w klasie menu
mają być przechowywane obiekty klasy menu_item
.
Co mam zrobić aby móc wywoływać funkcje wskazywane przez zmienne typu menu_item_func
zarówno wewnątrz klasy jak i przechowywać wskaźniki typu menu_item_func
do funkcji poza klasą?
Podczas kompilacji main.cpp
otrzymuję błąd
g++ -o main main.cpp menu.cpp 10:28:51
menu.cpp: In constructor ‘menu::menu(const std::string&)’:
menu.cpp:14:43: error: no matching function for call to ‘menu_item::menu_item(<brace-enclosed initializer list>)’
14 | items.push_back(menu_item{"Quit", quit});
| ^
In file included from menu.cpp:1:
menu.h:14:5: note: candidate: ‘menu_item::menu_item(const menu_item&)’
14 | menu_item(const menu_item& item) : title{item.title}, action{item.action} {}
| ^~~~~~~~~
menu.h:14:5: note: candidate expects 1 argument, 2 provided
menu.h:12:5: note: candidate: ‘menu_item::menu_item(const std::string&, menu_item_func)’
12 | menu_item(const std::string& title_val, menu_item_func action_val)
| ^~~~~~~~~
menu.h:12:60: note: no known conversion for argument 2 from ‘<unresolved overloaded function type>’ to ‘menu_item_func’ {aka ‘void (*)()’}
12 | menu_item(const std::string& title_val, menu_item_func action_val)
| ~~~~~~~~~~~~~~~^~~~~~~~~~
menu.h:11:5: note: candidate: ‘menu_item::menu_item(const std::string&)’
11 | menu_item(const std::string& title_val) : title{title_val} {}
| ^~~~~~~~~
menu.h:11:5: note: candidate expects 1 argument, 2 provided
menu.cpp: In constructor ‘menu::menu(const std::string&, const std::vector<menu_item>&)’:
menu.cpp:21:43: error: no matching function for call to ‘menu_item::menu_item(<brace-enclosed initializer list>)’
21 | items.push_back(menu_item{"Quit", quit});
| ^
menu.h:14:5: note: candidate: ‘menu_item::menu_item(const menu_item&)’
14 | menu_item(const menu_item& item) : title{item.title}, action{item.action} {}
| ^~~~~~~~~
menu.h:14:5: note: candidate expects 1 argument, 2 provided
menu.h:12:5: note: candidate: ‘menu_item::menu_item(const std::string&, menu_item_func)’
12 | menu_item(const std::string& title_val, menu_item_func action_val)
| ^~~~~~~~~
menu.h:12:60: note: no known conversion for argument 2 from ‘<unresolved overloaded function type>’ to ‘menu_item_func’ {aka ‘void (*)()’}
12 | menu_item(const std::string& title_val, menu_item_func action_val)
| ~~~~~~~~~~~~~~~^~~~~~~~~~
menu.h:11:5: note: candidate: ‘menu_item::menu_item(const std::string&)’
11 | menu_item(const std::string& title_val) : title{title_val} {}
| ^~~~~~~~~
menu.h:11:5: note: candidate expects 1 argument, 2 provided
menu.cpp: In member function ‘bool menu::loop()’:
menu.cpp:35:1: warning: no return statement in function returning non-void [-Wreturn-type]
35 | }
| ^
Kod C++
~/programy_cpp/linked_list ❯ cat menu.h 10:29:58
#ifndef MENU_H
#define MENU_H
#include <iostream>
#include <string>
#include <vector>
typedef void (*menu_item_func)();
struct menu_item {
menu_item(const std::string& title_val) : title{title_val} {}
menu_item(const std::string& title_val, menu_item_func action_val)
: title{title_val}, action{action_val} {}
menu_item(const menu_item& item) : title{item.title}, action{item.action} {}
menu_item& operator=(const menu_item& rhs);
friend std::ostream& operator<<(std::ostream& lhs, const menu_item& rhs);
std::string title{};
menu_item_func action{};
};
class menu {
public:
menu(const std::string& title_val);
menu(const std::string& title_val, const std::vector<menu_item>& items_val);
menu(const menu& menu_val);
bool loop();
private:
void quit();
bool active{false};
std::string title{};
std::vector<menu_item> items{};
};
#endif // MENU_H
~/programy_cpp/linked_list ❯ cat menu.cpp 10:30:08
#include "menu.h"
menu_item& menu_item::operator=(const menu_item& rhs) {
title = rhs.title;
action = rhs.action;
return *this;
}
std::ostream& operator<<(std::ostream& lhs, const menu_item& rhs) {
return lhs << rhs.title;
}
menu::menu(const std::string& title_val) : title{title_val} {
items.push_back(menu_item{"Quit", quit});
}
menu::menu(const std::string& title_val, const std::vector<menu_item>& items_val) : title{title_val} {
for (const menu_item& item : items) {
items.push_back(item);
}
items.push_back(menu_item{"Quit", quit});
}
menu::menu(const menu& menu_val) {
for (const menu_item& item : menu_val.items) {
items.push_back(item);
}
items.push_back(menu_item{"Quit", });
}
bool menu::loop() {
while (active) {
}
}
void menu::quit() {
active = false;
}
~/programy_cpp/linked_list ❯ cat main.cpp 10:30:12
#include <iostream>
/*#include <string>*/
/*#include "linked_list.h"*/
#include "menu.h"
void display_sth() {
std::cout << "test\n";
}
int main() {
menu_item item{"test", display_sth};
menu test{"abc", {item}};
return 0;
}