Search code examples
c++templatesc++14variadic-templatessfinae

Why does the following program not select the argument of the same type as the first template parameter?


I am trying to write a function such that f<T>(args..) returns the first parameter of type T.

The following program seems to always select the first specialization thus printing 97 (ASCII code of 'a'). Though the second one wouldn't require converting char to int. Could someone please explain the behavior?

I am new to SFINAE and meta-programming.

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

Solution

  • Your code's first function parameter is in a non-deduced context. enable_if< expr, T >::type cannot deduce T. It is in a "non-deduced context".

    Being unable to deduce T, foo<int>( 7 ) cannot use that overload; the compiler does not know what T is. foo<int,int>(7) would call it.

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

    now T is in a deduced context. We aren't trying to deduce R (nor can we deduce from a return type).