2017-09-28 63 views
1

只需查询哪一个是较新版本的C++中更好的选择来处理成员函数的回调。 任何帮助将不胜感激,希望这个例子也会有所帮助。绑定或Lambda成员函数回调C++ 12

template<class T> 
void addCallBack(void(T::*someFunc)(int), T* instance) { 
    func = std::bind(someFunc, instance, _1); 
} 
std::function<void(int)> func ; 

template<class T> 
void addCallBack(T* instance) { 
    func = [&instance](int x) { 
     instance->someFunc(x); 
    } 
} 
std::function<void(int)> func; 
+0

定义“更好”。 – stark

+2

在表现方面(就我的观点而言,就清晰度而言),Lambdas几乎总是优于“绑定”。 – 0x5453

+0

更适合工作,正确的方式,良好的编程习惯等。 我知道在C++中做大多数事情的方法有100种,并且想知道在这种情况下是否存在正确的方法或者它有什么关系? – user3220058

回答

4

此:

template<class T> 
void addCallBack(T* instance) { 
    func = [&instance](int x) { 
     instance->someFunc(x); 
    } 
} 

被捕获由参考参数instance,其在addCallBack()末端超出范围,以便你最终悬空参考。所以,绝对是不是那。

你想要做的是:

func = [instance](int x){ instance->someFunc(x); } 

或者只是:

func = [=](int x){ instance->someFunc(x); } 

现在还不会成为一个功能上的差异&匕首;这之间

func = std::bind(&T::someFunc, instance, std::placeholders::_1); 

但拉姆达将是通常更易于阅读(因为它是在这种情况下),而且更容易内联,更能够做到任意复杂的事情。后两者在这种情况下并不重要 - 但是基本上总是更喜欢lambda表达式的好理由。


&dagger;当然,如果someFunc是一个重载名称,这是不行的,这是更喜欢lambda的另一个理由 - 它将始终有效。

+0

没有实际的功能差异,但实际上可以从std函数中谨慎地提取绑定表达式,因为类型(虽然非常复杂)不能保证像lambda一样是唯一的。所以不*没有*功能差异。理智的代码库只是没有实际的区别。 – Yakk