template argument deduction/substitution failed, when using std::function and std::bind
Solution 1
To figure out the problem let separate statements:
auto f = bind(&TestA::testa, &testA, _1, _2); // OK
test.setCallback(f); // <<--- Error is here
setCallback
needs to know type of T
and it can't deduce it from f
, so give it a type
test.setCallback<TYPE>(f); // TYPE: int, float, a class, ...
Solution 2
You can make type deduction work with some variant of:
template<typename CALLBACK>
void setCallback(CALLBACK cb) {
typedef CALLBACK::first_argument_type T;
static_assert(is_same_type<CALLBACK,function<void(T,int)>>::value);
...
}
This way CALLBACK can be determined by looking at the argument. It might get into trouble if bind doesn't actually return a std::function but rather something that can be cast as one. I'm not sure.
haipeng31
Updated on March 22, 2020Comments
-
haipeng31 about 4 years
I have a compile error when using std::function in a templated member function, the following code is a simple example:
#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; }
And come with the following compile error:
testtemplate.cpp: In function ‘int main()’:
testtemplate.cpp:29:92: error: no matching function for call to ‘Test::setCallback(std::_Bind_helper)(int, int), TestA, const std::_Placeholder<1>&, const std::_Placeholder<2>&>::type)’
testtemplate.cpp:29:92: note: candidate is: testtemplate.cpp:10:7: note: template void Test::setCallback(std::function)
testtemplate.cpp:10:7: note: template argument deduction/substitution failed:
testtemplate.cpp:29:92: note: ‘std::_Bind(TestA*, std::_Placeholder<1>, std::_Placeholder<2>)>’ is not derived from ‘std::function’
I'm using C++11 and g++ 4.7