我試圖玩弄std :: function和std :: bind,並且我加入了一個問題。我想構建一個通用結構,它允許我將std :: function綁定到成員函數,而不必事先知道成員函數的參數。我寫這個東西訪問違反std :: function分配給lambda
template<typename Class, typename Return, typename ...Args>
struct Caller
{
private:
std::function<Return(Args ...)> callerFunction;
Caller(const Caller&) = delete;
Caller(Caller&&) = delete;
Caller& operator=(const Caller&) = delete;
public:
~Caller() = default;
Caller() = default;
Caller(Class& instance, Return(Class::*function)(Args...))
{
callerFunction = [&](Args... args) { return (instance.*function)(args...); };
}
Return operator() (Args ... args)
{
return callerFunction(args...);
}
};
FYI我知道,函數的自變量是按值傳遞(我遇到使用帶有可變參數模板普遍引用了一些問題,我將努力稍後)。
這裏的問題是,當我用operator()觸發函數時,我得到了訪問衝突錯誤。我試圖縮小這個問題,並創建了一個沒有可變參數的結構(允許成員函數只有一個int作爲參數),我看到將lambda賦給std :: function給了我相同的錯誤,但是如果我用佔位符的std :: bind一切都很好。
試驗地是這個
class A
{
public:
bool foo(int a)
{
std::cout << a << std::endl;
return true;
}
};
int main()
{
A a;
a.foo(9);
Caller<A, bool, int> caller(a, &A::foo);
caller(10);
std::cin.ignore();
}
使用拉姆達,做我需要保存的類的實例,以便正確地調用成員函數?
我很確定你有UB。在'Caller'的構造函數中,您通過值傳遞成員函數指針(因此將創建一個只存在於構造函數內部的指針副本),然後通過引用將其捕獲到lambda中。所以當你調用'caller(10)'時,指針超出了範圍。在這個例子中,'instance'很好,因爲你通過引用將它傳遞給了構造函數,當調用'caller(10)'時,'a'仍然在範圍內。 (雖然你應該假設未來會發生變化,並圍繞它進行設計。) – 0x5453
還值得注意的是,已經存在一個'std :: mem_fn',它應該可以在lambdas或std :: bind中正常工作。 – 0x5453
好了解。我不明白的是我如何解決這個問題。 關於實例:在程序啓動時,我將實例化一些類,這些變量將一直可用,直到程序結束。 – Astinog