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

依然范特西╮ 提交于 2019-12-12 10:45:41

问题


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

回答1:


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




回答2:


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
 }


来源:https://stackoverflow.com/questions/55775535/why-does-the-following-program-not-select-the-argument-of-the-same-type-as-the-f

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!