【问题标题】:CRTP inheriting from its default instantiationCRTP 从其默认实例化继承
【发布时间】:2013-05-03 16:41:57
【问题描述】:

我需要像这样表示一个层次结构:

template<typename T>
struct X
{
};

template<typename Derived = void>
struct Y : Y<void>
{
    //Note: not trying to use SFINAE here
    using DerivedType = typename std::enable_if<std::is_base_of<Y, Derived>::value, Derived>::type;
};
template<>
struct Y<void> : X<Y<void>>
{
};

struct Z : Y<Z>
{
};

Z 和 Y 都需要可实例化:

W<Y<>> wy;
W<Z> wz;

所有 Y 都必须是 Y 的实例,如果可能的话,我不希望有两个不同的名称来使其工作。 (这是我最后的手段)

问题是,我不知道如何进行这项工作。上面的代码显然不能按预期工作并且不能编译。有没有办法让它发挥作用,或者除了我已经提到的那个之外,你有什么替代方案的建议吗?

【问题讨论】:

  • 你想达到什么目的? std::enable_if 不会触发 SFINAE,而是一个硬错误。和static_assert(std::is_base_of&lt;Y,Derived&gt;::value)差别不大
  • 我不是在这里尝试使用 SFINAE,它应该会触发一个硬错误。
  • 那如果写成static_assert会更清楚:) 从编译器的角度来看效果是一样的,但是对其他维护者来说更清楚。
  • 啊,好的。我会确保改用它 - 它肯定看起来更好。
  • 顺便说一句,在上面的实现中,嵌套类型将始终为void,您忘记添加Derived 作为enable_if 的第二个参数(这是拆分为static_assert 和一个更简单的 typedef/using 声明,它们的编写和阅读都更简单。

标签: c++ templates inheritance template-meta-programming crtp


【解决方案1】:

如何重新排序:

template <typename> struct Y;

template <> struct Y<void> : X<Y<void>> { };

template <typename T = void> struct Y : Y<void> { };

【讨论】:

  • 谢谢,成功了!我对您的答案进行了更正,因为您继承了错误的内容并保留了默认值。
  • @LB--:哦,好的,我明白了。我现在添加了这些更改。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-27
  • 1970-01-01
相关资源
最近更新 更多