SFINAE专业班

Kla*_*aus 4 c++ sfinae c++14

我想写一个template class用SFINAE检查特征的东西.

正如我在帖子中所读到的那样,类不能"重载":模板重载和SFINAE只能处理函数但不能处理类

我写了以下代码:

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;
}
Run Code Online (Sandbox Code Playgroud)

但它完全失败了:

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;
Run Code Online (Sandbox Code Playgroud)

它接缝没有任何模板工作,但我没有得到编译器的提示为什么两个专业化失败.

Bar*_*rry 6

专业化必须与主要匹配.用于确定什么的查找规则X<AA>是首先匹配主要的,并添加默认类型,这使我们得到X<AA, void>,然后尝试将其与所有特化匹配.但是你的专业没有一个匹配,X<AA, void>所以你最终得到了主要的.主要不是完整类型,因此错误.

为什么他们都不匹配?因为你写道:

typename std::enable_if< std::is_same< int, typename T::TRAIT>::value, int >::type
Run Code Online (Sandbox Code Playgroud)

对于AA那些int不匹配的评价void,所以不考虑专业化.你只想要:

typename std::enable_if< std::is_same< int, typename T::TRAIT>::value>::type
Run Code Online (Sandbox Code Playgroud)

或者真的:

std::enable_if_t< std::is_same< int, typename T::TRAIT>::value>
Run Code Online (Sandbox Code Playgroud)

类似地,对于BB,第二个特化的第二个类型评估为 - unsigned int而不是void- 因此它也不匹配.