I've a simple template function do_something which returns an integer: 123.
template<typename T>
auto do_something(T input) {
std::this_thread::sleep_for(std::chrono::seconds(1));
return 123;
}
int main(int argc, char *argv[]) {
std::function<int(void)> function = std::bind(do_something<int>, 12);
function();
return 0;
}
With GCC 6.1.1, I get this error:
test.cpp: In function ‘int main(int, char**)’:
test.cpp:16:70: error: no matching function for call to ‘bind(<unresolved overloaded function type>, int)’
std::function<int(void)> function = std::bind(do_something<int>, 12);
^
In file included from /usr/include/c++/6.1.1/thread:39:0,
from test.cpp:4:
/usr/include/c++/6.1.1/functional:1331:5: note: candidate: template<class _Func, class ... _BoundArgs> typename std::_Bind_helper<std::__is_socketlike<_Func>::value, _Func, _BoundArgs ...>::type std::bind(_Func&&, _BoundArgs&& ...)
bind(_Func&& __f, _BoundArgs&&... __args)
^~~~
/usr/include/c++/6.1.1/functional:1331:5: note: template argument deduction/substitution failed:
test.cpp:16:70: note: couldn't deduce template parameter ‘_Func’
std::function<int(void)> function = std::bind(do_something<int>, 12);
^
In file included from /usr/include/c++/6.1.1/thread:39:0,
from test.cpp:4:
/usr/include/c++/6.1.1/functional:1359:5: note: candidate: template<class _Result, class _Func, class ... _BoundArgs> typename std::_Bindres_helper<_Result, _Func, _BoundArgs>::type std::bind(_Func&&, _BoundArgs&& ...)
bind(_Func&& __f, _BoundArgs&&... __args)
^~~~
/usr/include/c++/6.1.1/functional:1359:5: note: template argument deduction/substitution failed:
test.cpp:16:70: note: couldn't deduce template parameter ‘_Result’
std::function<int(void)> function = std::bind(do_something<int>, 12);
As you can see, the compiler cannot deduce the result type of the function.
Note that: clang++ 3.8.0 can compile that without any errors.
So my question: is there a way to specify the expected return value from a template function like in this case?
In C++14, you can just use auto as a return type.
auto type deduction is usually the same as template type deduction, but auto type deduction assumes that a braced initializer represents a std::initializer_list , and template type deduction doesn't. auto in a function return type or a lambda parameter implies template type deduction, not auto type deduction.
It looks like the compiler isn't sure about the type of the do_something<int>
- and I'm not sure if this is a compiler issue, or a language issue - but you can force the compiler to get its types sorted out by using do_something<int>
in a relatively trivial way before hand. For example the following compiles OK with both gcc and clang trunk versions (according to godbolt).
#include <functional>
template<typename T>
auto do_something(T input) {
return 123;
}
// Make the compiler workout the type of do_something<int> so we can use it later.
auto f = do_something<int>;
int main(int argc, char *argv[]) {
std::function<int(void)> function = std::bind(do_something<int>, 12);
function();
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With