类中的c ++ lambda表达式变量

时间:2014-01-28 20:15:53

标签: c++ class gcc c++11 lambda

我想保存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)’

2 个答案:

答案 0 :(得分: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;
    
  3. 解决方案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一样,就像函数指针一样。