【问题标题】:Using SFINAE for structs definitions [duplicate]使用 SFINAE 进行结构定义 [重复]
【发布时间】:2016-02-07 14:25:52
【问题描述】:

人们经常看到 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:对 N==4 使用 SFINAE 没有多大意义,请认为它是更复杂约束的占位符。

编辑:我不知道,SFINAE 仅适用于函数而不适用于类。如果只有两种可能性,std::conditinal 是一条出路。如果有两个以上不同的行为想要选择,那么question shown by the community 的答案是一个可能的解决方案。

【问题讨论】:

  • SFINAE 是关于函数重载解析,所以不清楚你的问题是什么意思。看起来你只是想要类模板专业化。

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


【解决方案1】:

看起来你想要的只是类模板专业化:

template <int N> struct S
{
    long v;
    // ...
};

template <> struct S<4>
{
    int v;
    // ...
};

可以通过将这些选择分解为单独的特征类模板,然后使用依赖类型(例如typename type_picker&lt;N&gt;::type v;)来管理复杂性。或者您可以使用现成的选择器:typename std::conditional&lt;N == 4, int, long&gt;::type v;

【讨论】:

  • 感谢您的建议!但是,如果我需要“N 是偶数”和“N 是奇数”甚至更复杂的不同实现怎么办。也可以通过模板特化的方式来完成吗?
  • @ead:是的,可以。您可以专注于一些中间选择器参数,例如一个布尔值,就像 std::conditional 一样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-08
  • 2011-06-22
  • 1970-01-01
  • 2021-02-09
  • 2017-04-15
  • 1970-01-01
相关资源
最近更新 更多