class 专攻 SFINAE
Specializing class with SFINAE
我想写一个 template class
用 SFINAE 检查特征。
因为 类 不能 "overloaded" 正如我在 post 中读到的那样: template overloading and SFINAE working only with functions but not classes
我写了下面的代码:
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;
}
但它只是失败了:
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 的模板有效,但我没有从编译器那里得到任何提示,为什么两个专业化都失败了。
专业必须与主要专业相匹配。确定 X<AA>
是什么的查找规则是首先匹配主要类型并添加默认类型,这使我们到达 X<AA, void>
,然后尝试将其与所有特化相匹配。但是 none 的专业与 X<AA, void>
匹配,因此您最终获得了初级。主要类型不是完整类型,因此会出现错误。
为什么 none 个匹配?因为你写道:
typename std::enable_if< std::is_same< int, typename T::TRAIT>::value, int >::type
对于计算为 int
的 AA
,它与 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
- 所以它也不匹配。
我想写一个 template class
用 SFINAE 检查特征。
因为 类 不能 "overloaded" 正如我在 post 中读到的那样: template overloading and SFINAE working only with functions but not classes
我写了下面的代码:
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;
}
但它只是失败了:
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 的模板有效,但我没有从编译器那里得到任何提示,为什么两个专业化都失败了。
专业必须与主要专业相匹配。确定 X<AA>
是什么的查找规则是首先匹配主要类型并添加默认类型,这使我们到达 X<AA, void>
,然后尝试将其与所有特化相匹配。但是 none 的专业与 X<AA, void>
匹配,因此您最终获得了初级。主要类型不是完整类型,因此会出现错误。
为什么 none 个匹配?因为你写道:
typename std::enable_if< std::is_same< int, typename T::TRAIT>::value, int >::type
对于计算为 int
的 AA
,它与 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
- 所以它也不匹配。