【问题标题】:Conditional explicit template instantiation条件显式模板实例化
【发布时间】:2012-12-18 03:16:12
【问题描述】:

除了预处理器,我如何有条件地启用/禁用显式模板实例化?

考虑:

template <typename T> struct TheTemplate{ /* blah */ };

template struct TheTemplate<Type1>;
template struct TheTemplate<Type2>;
template struct TheTemplate<Type3>;
template struct TheTemplate<Type4>;

在某些编译条件下,Type3与Type1相同,Type4与Type2相同。发生这种情况时,我得到一个错误。我想检测类型是相同的,而不是像在中那样在 Type3 和 Type4 上实例化

// this does not work
template struct TheTemplate<Type1>;
template struct TheTemplate<Type2>;
template struct TheTemplate<enable_if<!is_same<Type1, Type3>::value, Type3>::type>;
template struct TheTemplate<enable_if<!is_same<Type2, Type4>::value, Type4>::type>;

我已经转移了自己的注意力来尝试 enable_if 和 SFINAE(我相信我知道它们为什么会失败),但只有预处理器起作用了(呃)。我正在考虑将类型放入元组或可变参数中,删除重复项,然后将剩余部分用于实例化。

有没有办法根据模板参数类型有条件地启用/禁用显式模板实例化?

【问题讨论】:

  • 显式实例化一个类是否意味着隐式实例化所有基类型?
  • @jogojapan - 不,这个明确的 instantiation 不同于 specialization
  • 其实为什么重复显式实例化会出错?
  • @BenVoigt 这是一个错误,原因与函数的多个定义是错误的原因相同:ODR 违规。显式实例化不是模板(具有弱链接),它是一个类,因此只能定义一次。

标签: c++ templates c++11


【解决方案1】:
template <typename T> struct TheTemplate{ /* blah */ };

template<int> struct dummy { };

template struct TheTemplate<Type1>;
template struct TheTemplate<Type2>;
template struct TheTemplate<conditional<is_same<Type1, Type3>::value, dummy<3>, Type3>::type>;
template struct TheTemplate<conditional<is_same<Type2, Type4>::value, dummy<4>, Type4>::type>;

这仍然会产生四个显式实例化,但在Type3Type1 相同的情况下它们不会重复(除非Type1dummy&lt;3&gt;!)

【讨论】:

  • 缺点是dummy必须满足TheTemplate的要求,否则实例化会报错,所以dummy可能需要添加成员,或者你可以写一个部分TheTemplate&lt;dummy&lt;N&gt;&gt;的专业化
  • 或者,您可以打开您实例化的模板:template struct conditional&lt;is_same&lt;Type1, Type2&gt;::value, details::TheTemplate&lt;3&gt;, TheTemplate&lt;Type3&gt;&gt;::type::TheTemplate;。通过调用dummy 模板TheTemplate,它的一个特化的注入类名称称为TheTemplate,这样您在这两种情况下都可以访问::type::TheTemplate 并实例化任何类类型。类似于stackoverflow.com/a/13332744/34509
  • @Johannes 不错,我没想到
  • 示例中的 details:: 是什么?
  • @gerardw,我认为 Johannes 建议用 namespace details { template&lt;int&gt; struct TheTemplate { }; } 替换我的答案中的 dummy 类模板,这是一个不同的类模板但具有相同的名称
猜你喜欢
  • 1970-01-01
  • 2021-11-25
  • 1970-01-01
  • 1970-01-01
  • 2021-05-02
  • 2021-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多