2014-01-28 63 views
0

我想保存lambda表达式变量(如在第一代码块中)。问题是,然后我使用类(如第二个代码块)编译器返回一些错误。我不“知道如何解决它C++中的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; 
} 

编译:

[email protected] ~/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)’ 
+1

成员函数指针与函数指针不同。你可以看到错误的类型是不同的。 – chris

+0

除了下面的答案...您的test2.cpp中的lambda失败,因为它返回int而不是void。 – Rastaban

回答

1

问题是成员函数不是普通的函数,它们不能被分配给函数指针,因为它们所属的类型是它们类型的一部分。 另外,一个成员函数需要有一个被调用的对象,它将是函数代码中的this

您有几种解决方案:

  1. 只允许这是你的类

    void (*MyClass::func)(int); // but you can use it only with members of the class 
    
  2. 使用std::function

    typedef std::function<void(int)> func; 
    

解决方案2的成员函数最简单的就是std :: function被设计用于处理任何可调用的模板parammetters中相同的签名。 此外,它是唯一允许您存储闭包(来自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; 
} 
+0

谢谢你的解释。 “func = std :: bind(&my_default,this);”会返回错误(编译器),但像Brian Bi写道“std :: bind(&test :: my_default,this,std :: placeholders :: _ 1);”将不会返回错误。 – Heinrich

+0

啊是的,我总是很难提醒如何使用绑定,所以我只是使用lambdas。还有'mem_fun()'。 – Klaim

+0

我推荐'std :: function'路线,尽管第三个选项(取决于my_default的性质)是使my_default为静态的。 – Rastaban

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。

+0

谢谢!我可能忘记了成员函数和普通函数之间的区别是什么。 – Heinrich