std :: bind与可变参数模板和自动返回类型

时间:2018-08-01 22:44:48

标签: c++ variadic-templates c++17

this question中的代码之后,我有一个带有可变模板功能的std::bind。如果我尝试提供带有auto返回值的功能模板,则gcc会拒绝该程序:

#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);
}

编译错误为:

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);
        ^

据我所知,返回类型是我的工作说明的,只有auto返回类型是编译器无法处理的。

有没有一种方法可以在写代码时不知道返回类型的情况下从inv_impl返回? (我正在使用declval / decltype构造,但是我想知道是否还有更好的东西)

1 个答案:

答案 0 :(得分:4)

这绝对是gcc错误(已提交86826)。

解决方案是...不使用std::bind()。无论如何,几乎没有理由。 Lambda严格来说是优越的:

template <typename... Args>
auto inv(Args... args) {
  return [=]{ return inv_impl(args...); };
}