【问题标题】:Is it possible to specialize a template using a member enum?是否可以使用成员枚举来专门化模板?
【发布时间】:2011-05-31 10:23:00
【问题描述】:
struct Bar {
  enum { Special = 4 };
};

template<class T, int K> struct Foo {};
template<class T> struct Foo<T,T::Special> {};

用法:

Foo<Bar> aa;

使用 gcc 4.1.2 编译失败 它抱怨使用 T::Special 对 Foo 进行部分特化。如果Special 是一个类,则解决方案将是它前面的类型名。枚举(或整数)是否有与之等效的东西?

【问题讨论】:

  • 如果将 T::Special 替换为一个具体的整数(比如 99),它仍然无法在 g++ 4.4.0 下编译:'模板参数的数量错误(1,应该是 2) '.我意识到这是一个单独的问题,但编译器不应该接受这个吗?

标签: c++ templates enums template-specialization


【解决方案1】:

由于C++不允许Prasoon将explained作为explained,因此另一种解决方案是使用EnumToType类模板,

struct Bar {
  enum { Special = 4 };
};

template<int e>
struct EnumToType
{
  static const int value = e;
};

template<class T, class K> //note I changed from "int K" to "class K"
struct Foo
{};

template<class T> 
struct Foo<T, EnumToType<(int)T::Special> > 
{
   static const int enumValue = T::Special;
};

ideone 的示例代码:http://www.ideone.com/JPvZy


或者,您可以像这样简单地进行专业化(如果它解决了您的问题),

template<class T> struct Foo<T,Bar::Special> {};

//usage
Foo<Bar, Bar::Special> f;

【讨论】:

  • 请注意,您可以在EnumToType 中使用enum,而不是static const int。此外,EnumToType 的标准(C++0x,Boost)名称是 integral_constant
【解决方案2】:

非类型模板实参的类型不能依赖于偏特化的模板形参。

ISO C++03 14.5.4/9 说

部分特化的非类型实参表达式不应涉及部分特化的模板形参,除非实参表达式是简单标识符。

template <int I, int J> struct A {};
template <int I> struct A<I+5, I*2> {}; //error
template <int I, int J> struct B {};
template <int I> struct B<I, I> {};     //OK

所以像 template&lt;class T&gt; struct Foo&lt;T,T::Special&gt; {}; 这样的事情是非法的,因为 T::Special 依赖于 T

使用也是非法的。您提供了一个模板参数,但您需要提供两个。

【讨论】:

  • 这里为什么非类型模板参数的类型依赖于偏特化的模板参数呢?类型还是int,不是吗?
  • 我说的是模板参数(不是模板参数int KT::Special,它依赖于T
  • 啊。参数的类型取决于T,参数的类型是int
  • @James :添加了标准中的相关文本 :)
  • 你能解释一下它是什么意思吗:“部分特化非类型参数表达式”0_o。参数表达式可以部分特化吗?怎么样?,非常感谢:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多