为什么以下程序没有选择与第一个模板参数相同类型的参数?

问题描述 投票:6回答:2

我正在尝试编写一个函数,使f<T>(args..)返回类型为T的第一个参数。

以下程序似乎总是选择第一个专业化因此打印97'a'的ASCII代码)。虽然第二个不需要将char转换为int。有人可以解释一下这种行为吗?

我是SFINAE和元编程的新手。

  #include <iostream>
  using namespace std;

  template <typename T, typename ...Ts>
  T f(T a, Ts... args) {
    return a;
  }

  template <typename R, typename T, typename ...Ts>
  R f(typename enable_if<!is_same<R, T>::value, T>::type a, Ts... args) {
    return f<R>(args...);
  }

  int main() {
    cout << f<int>('a', 12);
  }
c++ templates c++14 variadic-templates sfinae
2个回答
4
投票

您的代码的第一个函数参数位于非推导的上下文中。 enable_if< expr, T >::type不能推断T。它处于“非推断的背景”中。

由于无法推断Tfoo<int>( 7 )不能使用那个超载;编译器不知道T是什么。 foo<int,int>(7)会称之为。

  template <typename R, typename T, typename ...Ts>
  typename enable_if<!is_same<R, T>::value, R>::type f(T a, Ts... args) 

现在T处于推断的背景中。我们不是试图推断R(我们也不能从返回类型推断)。


7
投票

std::enable_if的第二个模板参数应该是R,这是你想要的。

以下应该工作

 template < typename R, typename T, typename ...Ts>
 typename enable_if<!is_same<R, T>::value, R>::type f(T const& t, Ts&&... args) 
 //                                       ^^^         ^^^^^^^^^^^
 {
       return f<R>(std::forward<Ts>(args)...); // forward the args further
 }
© www.soinside.com 2019 - 2024. All rights reserved.