2017-02-21 216 views
1

這是我精簡的程序,我試圖使用函數變量在運行時修改類功能。所以 - 我聲明使用std::function模板和與兼容簽名函數myFunc成員變量m_func如何將成員函數賦值給使用std :: function定義的成員變量?

#include <functional> 
#include <iostream> 

struct T 
{ 
    T():m_func([](int){return true;}) {} 
    void assign() {m_func = &T::myFunc;} // <======== Problem is here 
    void call(int M) const {std::cout << m_func(M) << std::endl;} 
private: 
    bool myFunc(int N) {return (N >= 4);} 
    using func = std::function<bool(int)>; 
    func m_func; 
}; 

int main() 
{ 
    T t; 
    t.assign(); 
    t.call(6); 
} 

但是,編譯器(克++ 4.8.4與-std = C++ 11選項)給我一個錯誤長輸出,說template argument deduction/substitution failed和更多...

爲什麼我不能將myFunc函數分配給m_func變量?

+0

@nwp - 我不會介意你是否關閉它...謝謝 – HEKTO

回答

2
void assign() {m_func = &T::myFunc;} 

成員函數指針有一個隱含的this指針,需要在他們的簽名的第一個參數傳遞。或者使用std::bind先綁定,

void assign() { 
    m_func = std::bind(&T::myFunc, this, std::placeholders::_1); 
} 

或使用lambda。

void assign() { 
    m_func = [this](int arg){ return this->myFunc(arg) }; 
} 
3

如果你想在成員函數被調用當前對象上,然後你想:

m_func = std::bind(&T::myFunc, this, std::placeholders::_1); 
+2

我想你錯過了一個佔位符。 –

+0

@ RichardJ.RossIII:我確實,謝謝! –

4

非靜態成員函數指針不能被分配到std::function直接。這個問題的一般解決方法是將this指針捆綁成這樣的拉姆達:

void assign() { 
    m_func = [this](int N) { 
     return this->myFunc(N); 
    }; 
} 

在你的情況,似乎簡單到只是讓myFunc靜態的。

struct T 
{ 
    T() :m_func([](int) {return true; }) {} 
    void assign() { m_func = &T::myFunc; } 
    void call(int M) const { std::cout << m_func(M) << std::endl; } 
private: 
    static bool myFunc(int N) { return (N >= 4); } 
// ^^^^^^ static methods can be assigned to std::function directly 
    using func = std::function<bool(int)>; 
    func m_func; 
}; 
+0

謝謝!我無法使'myFunc'成爲靜態的,因爲在實際中它需要訪問一堆成員變量 – HEKTO

1

正如@Kerrek SB上面提到的,你可以使用std::bind

然而,最好使用lambda,因爲它可以有更少的開銷:

m_func = [this] (int N) {return myFunc(N);}; 
+0

至於開銷 - 你是指在這個任務期間的開銷,還是在'm_func'調用期間的開銷? (我真的關心第二個案例) – HEKTO

+0

其實我會說他們兩個。 – Telokis

相關問題