Specialized class with SFINAE

I want to write template classthat checks for a trait using SFINAE.

Since classes cannot be "overloaded", as I read in this article: template overloading, and SFINAE only works with functions, but not with classes

I wrote the following code:

class AA { public: using TRAIT = int; };
class BB { public: using TRAIT = float; };

template < typename T, typename UNUSED = void> class X;

template < typename T>
class X<T, typename std::enable_if< std::is_same< int, typename T::TRAIT>::value, int >::type>
{
    public:
        X() { std::cout << "First" << std::endl; }
 };

template < typename T>
class X<T, typename std::enable_if< !std::is_same< int, typename T::TRAIT>::value, unsigned int >::type>
{
    public:
        X() { std::cout << "Second" << std::endl; }
};

int main()
{
    X<AA> a;
    X<BB> b;
}

But it just fails:

error: aggregate 'X<AA> a' has incomplete type and cannot be defined
         X<AA> a;
               ^

error: aggregate 'X<BB> b' has incomplete type and cannot be defined
         X<BB> b;

None of the patterns seem to work, but I don't get any hint at the compiler why both specializations fail.

+4
source share
1 answer

. , X<AA> , , X<AA, void>, . X<AA, void>, . , .

? :

typename std::enable_if< std::is_same< int, typename T::TRAIT>::value, int >::type

AA, int, void, . :

typename std::enable_if< std::is_same< int, typename T::TRAIT>::value>::type

:

std::enable_if_t< std::is_same< int, typename T::TRAIT>::value>

, BB unsigned int void - .

+6

All Articles