簡體   English   中英

std :: bind綁定函數

[英]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只是一個可調用對象,它調用上文提到的可調用對象fsome_fun(f) ,它具有some_fun參數所期望的簽名。

我想念什么嗎? 我可能不知道如何實際混合std::bindstd::function

std::bind表達式, boost::bind前任一樣,支持一種合成操作。 您對w表達式大致等於

auto w=std::bind(some_fun,  std::bind(&foo::bar<int>, x, std::placeholders::_1) );

以這種方式嵌套的綁定被解釋為

  1. 計算x.bar<int>(y)的值,其中y是傳遞到結果函子的第一個參數。
  2. 將該結果傳遞給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<>::valuef的類型上為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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM