簡體   English   中英

std::function 和 std::bind:如何使用 function 模板加載 std::bind

[英]std::function and std::bind: how to load a std::bind with a function template

我使用 function 模板來加載 std::bind obj,我的代碼:

#include <iostream>
#include <functional>

template<typename RT_, typename ...Args>
void installCallback(const char name[], const std::function<RT_(Args...)> &func)
{

}

int add(int a, int b)
{
    return a + b;
}

int main(int argc, char *argv[])
{

    installCallback("add01", std::bind(add, std::placeholders::_1, std::placeholders::_2));
    installCallback<int, int, int>("add01", std::bind(add, std::placeholders::_1, std::placeholders::_2));// didn't work either

    // this work well
    std::function<int(int, int)> fun = std::bind(add, std::placeholders::_1, std::placeholders::_2);
    installCallback("add02", fun);
    return 0;
}

,我得到了這個錯誤:

 /home/tong/Documents/awesome_auto_drive/awe_auto/sample/module/main.cpp:20:90: error: no matching function for call to 'installCallback(const char [6], std::_Bind_helper<false, int (&)(int, int), const std::_Placeholder<1>&, const std::_Placeholder<2>&>::type)' 20 | installCallback("add01", std::bind(add, std::placeholders::_1, std::placeholders::_2)); | ^ $./main.cpp:6:6: note: candidate: 'template<class RT_, class... Args> void installCallback(const char*, std::function<_Res(_ArgTypes...)>&&)' 6 | void installCallback(const char name[], std::function<RT_(Args...)> &&func) | ^~~~~~~~~~~~~~~ $./main.cpp:6:6: note: template argument deduction/substitution failed: $./main.cpp:20:90: note: 'std::_Bind_helper<false, int (&)(int, int), const std::_Placeholder<1>&, const std::_Placeholder<2>&>::type' {aka 'std::_Bind<int (*(std::_Placeholder<1>, std::_Placeholder<2>))(int, int)>'} is not derived from 'std::function<_Res(_ArgTypes...)>' 20 | installCallback("add01", std::bind(add, std::placeholders::_1, std::placeholders::_2)); | ^ sample/module/CMakeFiles/module.dir/build.make:62: recipe for target 'sample/module/CMakeFiles/module.dir/main.cpp.o' failed make[2]: *** [sample/module/CMakeFiles/module.dir/main.cpp.o] Error 1 CMakeFiles/Makefile2:2665: recipe for target 'sample/module/CMakeFiles/module.dir/all' failed make[1]: *** [sample/module/CMakeFiles/module.dir/all] Error 2 Makefile:129: recipe for target 'all' failed make: *** [all] Error 2

誰能告訴我,發生了什么?

您遇到了模板 function 參數推導規則。 std::bind不返回std::function ,並且您為Args...傳遞的int只是Args... ... 的前綴。 所以 C++ 試圖推斷出Args...並因該錯誤而失敗。

快速修復是

template<class Sig>
void installCallback(const char name[], const std::function<Sig> &func)

然后

installCallback<int(int, int)>

這使得installCallback的主體失去了Args...

現在,

installCallback("add01", std::bind(add, std::placeholders::_1, std::placeholders::_2));

無法工作,因為bind (a) 不是 std function,並且 (b) 不知道它的參數類型是什么。

在這里也毫無意義。

installCallback("add01", add);

在邏輯上是等價的,並且較少充滿噪音。 它仍然無法編譯; 但是在這將:

installCallback("add01", std::function(add));

由於扣除指南。 綁定版本不會。

作為一般規則,如果您使用標准綁定,請改用 lambda。 ,lambda 可以機械地替換 95% 的綁定使用,在中,它變為 99.9%,剩下的 0.1% 是綁定的特性,你可能不應該使用並且不知道存在(通常直到它存在)以令人驚訝的方式破壞您的代碼;將 std 綁定傳遞給 std 綁定)。

我喜歡@yakk-adam-nevraumont 的回答。 我認為它非常清楚並且恰當地解釋了事情; 到目前為止最好的答案,所以我贊成它。 我唯一能做出的其他貢獻是,我能夠得出一個類似的結論(推導規則不會產生std::function )使用 boost 庫來消除每個表達式的打印類型名稱。 請參閱下面從提供的示例@JoeT 修改的代碼和此處的工作片段。

您會注意到fun2的推導類型與fun1的顯式類型不同。

#include <functional>
#include <iostream>
#include <typeinfo>
#include <boost/core/demangle.hpp>

template<typename RT_, typename ...Args>
void installCallback(const char name[], const std::function<RT_(Args...)> &func)
{

}

int add(int a, int b)
{
    return a + b;
}

int main(int argc, char *argv[])
{
    auto fun1 = std::bind(add, std::placeholders::_1, std::placeholders::_2);
    std::function<int(int, int)> fun2 = std::bind(add, std::placeholders::_1, std::placeholders::_2);
    char const* name = typeid( fun1 ).name();

    // Outputs: std::_Bind<int (*(std::_Placeholder<1>, std::_Placeholder<2>))(int, int)>
    std::cout << boost::core::demangle(typeid(fun1).name()) << std::endl;

    // Outputs: std::function<int (int, int)>
    std::cout << boost::core::demangle(typeid(fun2).name()) << std::endl;

    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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