Why does the following program not select the argu

2019-06-20 01:07发布

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

2条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-06-20 01:49

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).

查看更多
▲ chillily
3楼-- · 2019-06-20 01:55

The second template argument of the std::enable_if should be the R, which is what you desire to have.

Following should work

 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
 }
查看更多
登录 后发表回答