【问题标题】:Derive all template<derived> instances from template<base>从 template<base> 派生所有 template<derived> 实例
【发布时间】:2014-07-31 13:25:29
【问题描述】:

是否可以从以基类为参数的实例中派生所有以派生类为参数的模板实例?

在代码中:

class Base{};

class Derived1 : Base{};

class Derived2 : Base{};

template<typename T>
class Templ /*: Templ<Base> if T derives from Base*/ 
{};

如何做到这一点?

【问题讨论】:

  • 如果参数不是从某个东西派生的,那么类必须从什么派生?如果 Derive 继承自 Base(其中 base 是任意类型或非常具体),它必须“一般”从 Templ 派生。

标签: c++ templates inheritance c++11


【解决方案1】:

为Templ&lt;Base&gt; 进行特化,然后使用 SFINAE 和 std::is_base_of 从 Templ&lt;Base&gt; 派生一个单独的特化。

template<typename T, typename V = void>
class Templ 
{};

template<>
class Templ<Base>
{};

template<bool B, typename R = void>
using enable_if_t = typename std::enable_if<B, R>::type;

template<typename T>
class Templ<T, enable_if_t<std::is_base_of<Base, T>::value>>
    : public Templ<Base>
{};

【讨论】:

  • 如果我理解正确,这会尝试实例化专业化Templ&lt;T, enable_if_t&lt;bla&gt;&gt;。因此,如果enable_if 没有成员 typedef type,则替换失败并且模板不是专用的。但如果enable_if 确实有type,则替换成功,因此模板是专用的并派生自Templ&lt;Base&gt;,对吗?
  • 如果您从条件中排除 Base enable_if_t&lt;std::is_base_of&lt;Base, T&gt;::value &amp;&amp; !std::is_same&lt;Base, T&gt;::value&gt;,则无需专门化 Templ&lt;Base&gt;。
【解决方案2】:

这取决于你到底想做什么。如果您希望这仅适用于某些特定的已知基类,则可以轻松完成,例如就像 0x499602D2 的回答一样。

但是,我解释您的问题的方式是,您希望有一个模板,该模板源自其参数基类的实例化,无论是哪种情况。这在标准 c++ 中是不可能的(目前),因为没有办法查询特定类型派生自哪个类,只有当它派生自特定类时。有关这方面的更多信息(以及未来可能的解决方案,请查看this question。

【讨论】:

  • 我希望 like 让它适用于任意基类,但 0x499602D2 的解决方案已经足够好,而且似乎可以工作。感谢您的链接,我每隔一天就会越来越多地退出 C++14!
  • @iFreilicht:嗯,afaik 提到的功能不是我也急切地等待这些功能的一部分。然而,它不会出现在 C++14 中。这是由标准委员会的反射研究小组进行的,该小组还没有准备好 iirc 的提案,所以我预计在 2017 年之前不会有任何事情,可能会更晚。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-25
  • 1970-01-01
  • 1970-01-01
  • 2012-03-12
  • 2012-07-07
  • 1970-01-01
  • 2018-07-06
相关资源
最近更新 更多