使用SFINAE进行结构定义

时间:2016-02-07 14:25:52

标签: c++ templates c++11 struct sfinae

人们经常看到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的答案是可能的解决方案。

1 个答案:

答案 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;