[英]std::bind a bound function
我在確定為什么無法編譯時遇到了麻煩。 我有一些lambda函數,它基於某些參數返回std::function
。
我將問題縮小到此代碼段(不使用lambda,但完美地再現了我的錯誤):
#include <functional>
#include <iostream>
struct foo {
template<class T>
void bar(T data) {
std::cout << data << "\n";
}
};
void some_fun(const std::function<void(int)> &f) {
f(12);
}
int main() {
foo x;
auto f = std::bind(&foo::bar<int>, x, std::placeholders::_1);
auto w = std::bind(some_fun, f);
w();
}
調用w()
會產生一些可愛的gcc錯誤輸出,其中我無法弄清楚出了什么問題。 這是gcc 4.6.1回顯的錯誤:
g++ -std=c++0x test.cpp -o test
test.cpp: In function ‘int main()’:
test.cpp:20:7: error: no match for call to ‘(std::_Bind<void (*(std::_Bind<std::_Mem_fn<void (foo::*)(int)>(foo, std::_Placeholder<1>)>))(const std::function<void(int)>&)>) ()’
/usr/include/c++/4.6/functional:1130:11: note: candidates are:
/usr/include/c++/4.6/functional:1201:2: note: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) [with _Args = {_Args ...}, _Result = _Result, _Functor = void (*)(const std::function<void(int)>&), _Bound_args = {std::_Bind<std::_Mem_fn<void (foo::*)(int)>(foo, std::_Placeholder<1>)>}]
/usr/include/c++/4.6/functional:1215:2: note: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) const [with _Args = {_Args ...}, _Result = _Result, _Functor = void (*)(const std::function<void(int)>&), _Bound_args = {std::_Bind<std::_Mem_fn<void (foo::*)(int)>(foo, std::_Placeholder<1>)>}]
/usr/include/c++/4.6/functional:1229:2: note: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) volatile [with _Args = {_Args ...}, _Result = _Result, _Functor = void (*)(const std::function<void(int)>&), _Bound_args = {std::_Bind<std::_Mem_fn<void (foo::*)(int)>(foo, std::_Placeholder<1>)>}]
/usr/include/c++/4.6/functional:1243:2: note: template<class ... _Args, class _Result> _Result std::_Bind<_Functor(_Bound_args ...)>::operator()(_Args&& ...) const volatile [with _Args = {_Args ...}, _Result = _Result, _Functor = void (*)(const std::function<void(int)>&), _Bound_args = {std::_Bind<std::_Mem_fn<void (foo::*)(int)>(foo, std::_Placeholder<1>)>}]
在這里, f
應該是一些可調用的對象,它以int作為參數並使用x.bar(int)
進行調用。 另一方面, w
只是一個可調用對象,它調用上文提到的可調用對象f
的some_fun(f)
,它具有some_fun
參數所期望的簽名。
我想念什么嗎? 我可能不知道如何實際混合std::bind
和std::function
。
std::bind
表達式, boost::bind
前任一樣,支持一種合成操作。 您對w
表達式大致等於
auto w=std::bind(some_fun, std::bind(&foo::bar<int>, x, std::placeholders::_1) );
以這種方式嵌套的綁定被解釋為
x.bar<int>(y)
的值,其中y
是傳遞到結果函子的第一個參數。 some_fun
。 但是x.bar<int>(y)
返回void,而不是任何函數類型。 這就是為什么它不能編譯的原因。
正如K-ballo指出的那樣,使用boost::bind
可以使用boost::protect
解決此問題。 正如Kerrek SB和ildjarn所指出的,解決此問題的一種方法是:不要將auto
用於f
。 您不希望f
具有綁定表達式的類型。 如果f
具有其他類型,則std::bind
將不會嘗試應用函數組合規則。 例如,您可以給f
類型std::function<void(int)>
:
std::function<void(int)> f = std::bind(&foo::bar<int>, x, std::placeholders::_1);
auto w = std::bind(some_fun, f);
由於f
實際上沒有綁定表達式的類型,因此std::is_bind_expression<>::value
在f
的類型上為false,因此第二行的std::bind
表達式僅將值傳遞給逐字記錄,而不是嘗試應用功能組合規則。
some_fun
想要使用const std::function<void(int)> &
類型的參數。
std :: bind返回您試圖作為some_fun參數傳遞的“未指定類型T的函數對象”(請參見提供的鏈接,“返回值”部分)。
看來這會引起問題,因為不需要此參數類型。
查看: http : //en.cppreference.com/w/cpp/utility/functional/bind
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.