Why compile error with enable_if

前端 未结 5 1924
小蘑菇
小蘑菇 2020-12-09 07:50

Why this does not compile with gcc48 and clang32?

#include 

template  
struct S {

    template 
    typename         


        
相关标签:
5条回答
  • Well, I am not sure what you wanted to do, but maybe this code will help:

    #include <iostream>
    
    template <int N>
    struct S {
    
        template<class T=int>
        typename std::enable_if<N==1, T>::type
        f(T t) {return 1;}
    
        template<class T=int>
        typename std::enable_if<N!=1, T>::type
        f(T t) {return 2;}
    };
    
    int main()
    {
        S<1> s1;
        S<2> s2;
        std::cout << s1.f(99) << " " << std::endl << s2.f(5);
    }
    

    This prints 1 and 2.

    0 讨论(0)
  • 2020-12-09 08:35

    To get std::enable_if to work like this, you are relying on SFINAE. Unfortunately, at the point where you declare

    S<1> s1;
    

    it will instantiate all of S<1>'s member declarations. SFINAE will only come into play at this point if S<1> were an ill-formed construct. It is not. Unfortunately, it contains a function which is invalid, thus the instantiation of S<> is invalid.

    For things like this, I might defer to a seperate template struct:

    template <bool B>
    struct f_functor {
        template <typename T>
        static int f(T t) { return 1; }
    };
    
    template <>
    struct f_functor<false> {
        template <typename T>
        static int f(T t) { return 2; }
    };
    
    template <int N> 
    struct S {
    
        template<class T> 
        typename int f(T t) { return f_functor<N==1>::f(t); }
    };
    
    0 讨论(0)
  • 2020-12-09 08:39

    For this case you could think about not using enable_if at all. It is posible to simply specialise f:

    template <int N> 
    struct S {
        template<class T> int f(T t);
    };
    
    template<int N>
    template<class T>
    int S<N>::f(T t) { return 2; }
    
    template<>
    template<class T>
    int S<1>::f(T t) { return 1; }
    
    int main() {
        S<1> s1;
        return s1.f(99);
    }
    
    0 讨论(0)
  • 2020-12-09 08:56

    Use a default boolean template parameter, like this:

    template <int N> 
    struct S {
    
        template<class T, bool EnableBool=true> 
        typename std::enable_if<N==1 && EnableBool, int>::type
        f(T t) {return 1;};
    
        template<class T, bool EnableBool=true> 
        typename std::enable_if<N!=1 && EnableBool, int>::type
        f(T t) {return 2;};
    };
    
    0 讨论(0)
  • 2020-12-09 08:57

    Because you use enable_if without using the template parameter T in your function templates. If you want to specialize for when the struct S has a certain template parameter value N, you'll need to use class template specialization.

    template <int N, class Enable = void> 
    struct S {  };
    
    template <int N>
    struct S<N, typename std::enable_if<N == 1>::type>
    {
      ....
    };
    
    0 讨论(0)
提交回复
热议问题