2014-01-28 67 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