人们经常看到SFINAE用于功能。例如:
#include <type_traits>
#include <iostream>
template<int N>//version for N!=4
typename std::enable_if<N==4, int>::type val(){
return N;
}
template<int N>//version for N==4
typename std::enable_if<N!=4, int>::type val(){
return 2*N;
}
int main(){
std::cout<<val<4>()<<std::endl;//prints: 4, version N==4
std::cout<<val<5>()<<std::endl;//prints: 10, version N==10
}
我可以使用SNIFAE不仅用于功能,还用于结构?类似的东西:
...
template<int N, typename std::enable_if<N==4>::type>
struct S{
int v;//for N==4 v should be int
...
};
template<int N, typename std::enable_if<N!=4>::type>
struct S{
long v;//for N!=4 v should be long
...
};
即使我不尝试实例化,编译器也不接受它。
将SFINAE与结构一起使用的正确方法是什么?
或者应该使用不同的技术来实现为不同的N值设置不同的struct-member的目标?
PS:对于N == 4使用SFINAE没有多大意义,请将其视为更复杂约束的占位符。
编辑:我不知道,SFINAE仅用于功能,而不用于课程。如果只有两种可能性,那么std::conditinal
就是一种出路。如果有两个以上的不同行为可供选择,那么question shown by the community的答案是可能的解决方案。
答案 0 :(得分:3)
看起来你想要的只是类模板专业化:
template <int N> struct S
{
long v;
// ...
};
template <> struct S<4>
{
int v;
// ...
};
可以通过将这些选择分解为单独的特征类模板,然后使用依赖类型(例如typename type_picker<N>::type v;
)来管理复杂性。或者您可以使用现成的选择器:typename std::conditional<N == 4, int, long>::type v;
。