问题
Following the code in this question, I have a std::bind
with a variadic template function. If I try to provide a function template with auto
return, gcc rejects the program:
#include <functional>
template <typename... Args
auto inv_impl(Args... a) { return (a + ...); }
template <typename... Args>
auto inv(Args... args) {
auto bound = std::bind(&inv_impl<Args...>, args...);
return bound;
}
int main() {
auto b = inv(1, 2);
}
The compile error is:
foo.cc: In instantiation of ‘auto inv(Args ...) [with Args = {int, int}]’:
foo.cc:41:30: required from here
foo.cc:36:25: error: no matching function for call to ‘bind(<unresolved overloaded function type>, int&, int& ’
auto bound = std::bind(&inv_impl<Args...>, args...);
~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from foo.cc:2:
/usr/include/c++/8.1.1/functional:808: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++/8.1.1/functional:808:5: note: template argument deduction/substitution failed:
foo.cc:36:25: note: couldn't deduce template parameter ‘_Func’
auto bound = std::bind(&inv_impl<Args...>, args...);
~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from foo.cc:2:
/usr/include/c++/8.1.1/functional:832: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++/8.1.1/functional:832:5: note: template argument deduction/substitution failed:
foo.cc:36:25: note: couldn't deduce template parameter ‘_Result’
auto bound = std::bind(&inv_impl<Args...>, args...);
~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
foo.cc:37:10: error: unable to deduce ‘auto’ from ‘bound’
return bound;
^~~~~
foo.cc: In function ‘int main()’:
foo.cc:41:8: error: ‘void b’ has incomplete type
auto b = inv<int, int>(1, 2);
^
As far as I see, return types spelled out by me work, and it's only auto
return types that the compiler can't handle.
Is there a way I can return from inv_impl without knowing the return type at code-write time?
(I'm playing with declval
/decltype
constructs but I'm wondering if there's something better)
回答1:
This is definitely a gcc bug (filed 86826).
The solution is to just... not use std::bind()
. There's hardly ever a reason to anyway. Lambdas are strictly superior:
template <typename... Args>
auto inv(Args... args) {
return [=]{ return inv_impl(args...); };
}
来源:https://stackoverflow.com/questions/51643222/stdbind-with-variadic-template-and-auto-return-type