使用 SFINAE 进行结构定义
Using SFINAE for structs definitions
人们经常看到 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 值使用不同的结构成员的目标?
PS:将 SFINAE 用于 N==4 没有多大意义,请将其视为更复杂约束的占位符。
编辑: 我不知道 SFINAE 仅用于函数而不用于 类。如果只有两种可能,std::conditinal
是一条出路。如果有两种以上的不同行为可供选择,那么 question shown by the community 的答案是一种可能的解决方案。
看起来你想要的只是class模板专业化:
template <int N> struct S
{
long v;
// ...
};
template <> struct S<4>
{
int v;
// ...
};
可以通过将此类选择分解为单独的特征 class 模板,然后使用依赖类型(例如 typename type_picker<N>::type v;
)来管理复杂性。或者您可以使用现成的选择器:typename std::conditional<N == 4, int, long>::type v;
.
人们经常看到 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 值使用不同的结构成员的目标?
PS:将 SFINAE 用于 N==4 没有多大意义,请将其视为更复杂约束的占位符。
编辑: 我不知道 SFINAE 仅用于函数而不用于 类。如果只有两种可能,std::conditinal
是一条出路。如果有两种以上的不同行为可供选择,那么 question shown by the community 的答案是一种可能的解决方案。
看起来你想要的只是class模板专业化:
template <int N> struct S
{
long v;
// ...
};
template <> struct S<4>
{
int v;
// ...
};
可以通过将此类选择分解为单独的特征 class 模板,然后使用依赖类型(例如 typename type_picker<N>::type v;
)来管理复杂性。或者您可以使用现成的选择器:typename std::conditional<N == 4, int, long>::type v;
.