有時我需要將一些成員函數綁定到它的調用對象,以相同的方式處理成員函數和非成員函數。例如(該tipical回調爲例):綁定通用成員函數
#include <vector>
#include <functional>
void f(int){}
struct foo
{
void f(int){}
};
int main()
{
using namespace std::placeholders;
foo my_foo;
std::vector<std::function<void()>> functions;
functions.push_back(f);
functions.push_back([](int){});
functions.push_back(std::bind(&foo::f , my_foo , _1));
for(auto& function : functions)
{
function(0);
}
}
隨着越來越多參數的成員函數,更多的佔位符,我們需要把std::bind()
調用中。
現在考慮一個通用版本。不應該有問題,是不是?:
#include <vector>
#include <functional>
void f(int){}
struct foo
{
void f(int){}
};
template<typename FIRST , typename SECOND , typename THIRD>
class callback_list
{
using callback_t = std::function<void(FIRST,SECOND,THIRD>)>;
//Overload for non-member handlers:
void add(const callback_t& handler)
{
_handlers.push_back(handler);
}
//Overload for member handlers:
template<typename CLASS>
void add(CLASS& object_ref ,
void(CLASS::*member_function)(FIRST,SECOND,THIRD))
{
using namespace std::placeholders;
_handlers.push_back(std::bind(member_function ,
std::ref(object_ref) ,
_1 , _2 , _3
)
);
}
template<typename... ARGS>
void operator()(ARGS&&... args)
{
for(auto& handler : _handlers)
handler(std::forward<ARGS>(args)...);
}
private:
std::vector<callback_t> functions;
};
void f(int,int,int){}
struct foo
{
void f(int,int,int){}
};
int main()
{
using namespace std::placeholders;
foo my_foo;
callback_list<int,int,int> callbacks;
callbacks.add(f);
callbacks.add([](int,int,int){});
callbacks.add(my_foo , &foo::f);
callbacks(0,0,0);
}
好的。成員回調的add()
重載只是將對象綁定到成員函數,並且因爲回調有三個參數,所以我們使用三個佔位符。
但考慮一下:如果回調函數有多少個參數會怎樣?。
換句話說,我有什麼,如果callback_list
類模板與可變參數模板?:
template<typename... ARGS>
class callback_list{ ... };
我如何可以綁定一個可變參數函數與在std::bind()
調用點已知的任何功能參數定義做,也就是說,沒有指定數量的佔位符?
相關? http://stackoverflow.com/q/21192659/420683 – dyp
@dyp大聲笑我檢查了[這個](http://stackoverflow.com/questions/5608606/callback-with-variadic-template-to-ambiguous-overloads) ,[this](http://stackoverflow.com/questions/14803112/short-way-to-stdbind-member-function-to-object-instance-without-binding-param),[this](http:// stackoverflow.com/questions/11372855/stdbind-to-stdfunction)和[this](http://stackoverflow.com/questions/18380820/how-to-combine-stdbind-variadic-templates-and-perfect-forwarding)但我沒有找到該線程...非常感謝。 – Manu343726
那麼[lambda版本](http://stackoverflow.com/a/14803335/420683)也會起作用,不是嗎? – dyp