Template specialization and enable_if problems [duplicate]

别等时光非礼了梦想. 提交于 2019-11-26 08:19:42

问题


I am running into a problem regarding the appropriate usage of enable_if and template specialization.

After modifying the example (for confidentiality reasons), here\'s a comparable example:

I have function called \"less\" that checks if 1st arg is less than 2nd arg. Let\'s say I want to have 2 different kinds of implementations depending on the type of input - 1 implementation for integer and another for double.

The code that I have so far looks like this -

#include <type_traits>
#include <iostream>

template <class T,
          class = typename std::enable_if<std::is_floating_point<T>::value>::type>
     bool less(T a, T b) {
  // ....
}

template <class T,
          class = typename std::enable_if<std::is_integral<T>::value>::type>
     bool less(T a, T b) {
  // ....
}

int main() {
    float a;
    float b;
    less(a,b);
    return 0;
}

The above code does not compile because - It says that I am re-defining the less method.

Errors are:

Z.cpp:15:19: error: template parameter redefines default argument
          class = typename std::enable_if<std::is_integral<T>::value>::type>

                  ^
Z.cpp:9:19: note: previous default template argument defined here
          class = typename std::enable_if<std::is_floating_point<T>::value>::type>
                  ^

Z.cpp:16:11: error: redefinition of \'less\'
     bool less(T a, T b) {
          ^

Z.cpp:10:11: note: previous definition is here
     bool less(T a, T b) {
          ^

Z.cpp:23:5: error: no matching function for call to \'less\'
    less(a,b);
    ^~~~

Z.cpp:15:43: note: candidate template ignored: disabled by \'enable_if\'
      [with T = float]
          class = typename std::enable_if<std::is_integral<T>::value>::type>
                                          ^
3 errors generated.

Can someone point out what\'s the mistake here?


回答1:


Default template arguments are not part of the signature of a function template. So in your example you have two identical overloads of less, which is illegal. clang complains about the redefinition of the default argument (which is also illegal according to §14.1/12 [temp.param]), while gcc produces the following error message:

error: redefinition of 'template<class T, class> bool less(T, T)'

To fix the error move the enable_if expression from default argument to a dummy template parameter

template <class T,
          typename std::enable_if<std::is_floating_point<T>::value, int>::type* = nullptr>
     bool less(T a, T b) {
  // ....
}

template <class T,
          typename std::enable_if<std::is_integral<T>::value, int>::type* = nullptr>
     bool less(T a, T b) {
  // ....
}

Another option is to use enable_if in the return type, though I feel this is harder to read.

template <class T>
      typename std::enable_if<std::is_floating_point<T>::value, bool>::type 
      less(T a, T b) {
  // ....
}

template <class T>
     typename std::enable_if<std::is_integral<T>::value, bool>::type 
     less(T a, T b) {
  // ....
}


来源:https://stackoverflow.com/questions/29502052/template-specialization-and-enable-if-problems

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