我想保存lambda表达式变量(就像在第一个代码块中一样)。问题是,然后我使用类(如第二个代码块)编译器返回一些错误。我不知道如何解决它。
我希望有人可以帮助我并解释一下,为什么它不能像这样工作。感谢。
第一个代码:
// variable for function pointer
void (*func)(int);
// default output function
void my_default(int x) {
cout << "x =" << "\t" << x << endl << endl;
}
int main() {
cout << "Test Programm\n\n";
// 1. Test - default output function
cout << "my_default\n";
func = &my_default;
func(5);
// 2. Test - special output function 2
cout << "my_func2\n";
func = [](int x) { cout << "x =" << " " << x << endl << endl; };
func(5);
return 0;
}
第二代码:
class test {
private:
// variable for function pointer
void (*func)(int);
// default output function
void my_default(int x) {
cout << "x =" << "\t" << x << endl << endl;
}
public:
void dummy(void) {
// 1. Test - default output function
cout << "my_default\n";
func = &my_default;
func(5);
// 2. Test - special output function 2
cout << "my_func2\n";
func = [](int x)->int{ cout << "x =" << " " << x << endl << endl; };
func(5);
}
};
// entry
int main() {
cout << "Test Programm\n\n";
test a;
a.dummy();
return 0;
}
编译器:
pi@raspberrypi ~/dev/property $ gcc -std=c++0x -o test2 test2.cpp -lstdc++
test2.cpp: In member function ‘void test::dummy()’:
test2.cpp:491:17: error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say ‘&test::my_default’ [-fpermissive]
test2.cpp:491:17: error: cannot convert ‘void (test::*)(int)’ to ‘void (*)(int)’ in assignment
test2.cpp:496:77: error: invalid user-defined conversion from ‘test::dummy()::<lambda(int)>’ to ‘void (*)(int)’ [-fpermissive]
test2.cpp:496:28: note: candidate is: test::dummy()::<lambda(int)>::operator int (*)(int)() const <near match>
test2.cpp:496:28: note: no known conversion for implicit ‘this’ parameter from ‘int (*)(int)’ to ‘void (*)(int)’
答案 0 :(得分:1)
问题是成员函数不是普通函数,它们不能分配给函数指针,因为它们所属的类型是它们类型的一部分。
此外,成员函数需要有一个要调用的对象,它将是函数代码中的this
。
您有几种解决方案:
仅允许属于您班级成员的职能
void (*MyClass::func)(int); // but you can use it only with members of the class
typedef std::function<void(int)> func;
解决方案2是最简单的,因为std :: function旨在处理可以使用与模板参数中的签名相同的签名调用的任何内容。 此外,它是唯一允许您存储闭包(来自lambdas的对象)的解决方案。 有关详细信息,请参阅C++11 styled callbacks?。
class test {
private:
// variable for function pointer
std::function< void ( int )> func;
// default output function
void my_default(int x) {
cout << "x =" << "\t" << x << endl << endl;
}
public:
void dummy(void) {
// 1. Test - default output function
cout << "my_default\n";
func = std::bind(&test::my_default, this, std::placeholders::_1);
// or
func = [&]( int i ){ my_default( i ); };
func(5);
// 2. Test - special output function 2
cout << "my_func2\n";
func = [](int x)->int{ cout << "x =" << " " << x << endl << endl; };
func(5);
}
};
// entry
int main() {
cout << "Test Programm\n\n";
test a;
a.dummy();
return 0;
}
答案 1 :(得分:0)
成员函数与普通函数不同,因为必须有一个类的实例才能调用它(即,将成为*this
的对象)。您不能使普通函数指针变量指向成员函数。
如果要创建可以使用该类的任何实例调用的函数指针,则需要一个成员函数指针。你会写
void (test::*func)(int);
宣布它,
func = &test::my_default;
分配它,
(this->*func)(5);
来称呼它。当然,现在你不能使成员函数指针指向lambda。
另一方面,如果你想绑定this
作为实例并从成员函数创建一个普通函数,那么你实际上不能生成一个普通的函数指针。相反,你需要一个std::function
对象,
std::function<void(int)> func;
绑定如下:
func = std::bind(&test::my_default, this, std::placeholders::_1);
然后正常通话。 std::function
与lambdas一样,就像函数指针一样。