Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用std::function和std::bind时,模板参数推导/替换失败_C++_Function_Templates_Bind - Fatal编程技术网

C++ 使用std::function和std::bind时,模板参数推导/替换失败

C++ 使用std::function和std::bind时,模板参数推导/替换失败,c++,function,templates,bind,C++,Function,Templates,Bind,我在模板成员函数中使用std::function时出现编译错误,以下代码是一个简单的示例: #include <functional> #include <memory> using std::function; using std::bind; using std::shared_ptr; class Test { public: template <typename T> void setCallback(function<vo

我在模板成员函数中使用std::function时出现编译错误,以下代码是一个简单的示例:

#include <functional>
#include <memory>
using std::function;
using std::bind;
using std::shared_ptr;

class Test {
public:
     template <typename T>
     void setCallback(function<void (T, int)> cb); 
};

template <typename T>
void Test::setCallback(function<void (T, int)> cb)
{
    // do nothing
}

class TestA {
public:
    void testa(int a, int b) {   }
};


int main()
{
    TestA testA;
    Test test;
    test.setCallback(bind(&TestA::testa, &testA, std::placeholders::_1, std::placeholders::_2));
    return 0;
}
#包括
#包括
使用std::函数;
使用std::bind;
使用std::shared_ptr;
课堂测试{
公众:
模板
void setCallback(函数cb);
};
模板
void测试::setCallback(函数cb)
{
//无所事事
}
类种皮{
公众:
无效测试a(inta,intb){}
};
int main()
{
种皮;
试验;
setCallback(绑定(&TestA::TestA,&TestA,std::占位符::_1,std::占位符::_2));
返回0;
}
并出现以下编译错误:

testtemplate.cpp:在函数“int main()”中:

testtemplate.cpp:29:92:错误:没有用于调用的匹配函数 'Test::setCallback(std:_Bind_helper)(int,int), TestA,const std::_占位符和,const std::_占位符&>::类型)'

testtemplate.cpp:29:92:注:候选人是:testtemplate.cpp:10:7: 注意:模板void Test::setCallback(std::function)

testtemplate.cpp:10:7:注意:模板参数 扣除/替换失败:

testtemplate.cpp:29:92:注意:'std::_绑定(TestA*,std:_占位符, std::_占位符)>'不是从“std::function”派生的


我正在使用C++11和g++4.7来解决这个问题,让单独的语句:

auto f = bind(&TestA::testa, &testA, _1, _2); // OK
test.setCallback(f);                          // <<--- Error is here

您可以使用以下变量进行类型推断:

template<typename CALLBACK>
void setCallback(CALLBACK cb) {
  typedef CALLBACK::first_argument_type T;
  static_assert(is_same_type<CALLBACK,function<void(T,int)>>::value);
  ...
}
模板
void setCallback(回调cb){
typedef回调::第一个参数\u类型T;
静态断言(与类型::值相同);
...
}

这样,可以通过查看参数来确定回调。如果bind实际返回的不是std::函数,而是可以转换为std::函数的函数,那么它可能会遇到麻烦。我不确定。

test.setCallback(bind…)
bind
的结果不是一个
std::function
,因此没有参数推断。请告诉我,你认为编译器可以如何推断出
T
的结果。@Xeo我是模板的新手,我不知道dededece是如何工作的。有什么实质性的帮助吗?@user1679133:一般来说,当
std::function
是一个参数时,除非传递
std::function
,否则必须完整地拼写类型。lambda比
std::bind
模板更合适。模板太难了,我用了一整个下午来处理这个问题,最后,我无法解决,谢谢你的解释。顺便问一下,你能给我一些学习的建议吗template@user1679133:每天编程和练习,这是学习编程概念的唯一途径。我们都是这样做的。并阅读Stackoverflow中的Q&A。
template<typename CALLBACK>
void setCallback(CALLBACK cb) {
  typedef CALLBACK::first_argument_type T;
  static_assert(is_same_type<CALLBACK,function<void(T,int)>>::value);
  ...
}