【问题标题】:Typedef to create a (fake) derived class in CRTP - impossible?Typedef 在 CRTP 中创建(假)派生类 - 不可能吗?
【发布时间】:2017-05-22 10:38:51
【问题描述】:

如何为 CRTP 中的派生类起别名?

是不是 (Derived1) 根本不可能,我必须完全创建一个新类 (Derived2)?

template<class CRTP,class T>class Base{};

//These don't work.
//template<class T> using Derive1 = Base<Derive1<T>,T>;
//template<class T> using Derive1 = Base<Base,T>;
//template<class T> using Derive1 = Base<Base<T>,T>;
//template<class T> using Derive1 = Base<Base<Base<T>>,T>;

//This works.
template<class T> class Derive2 : public Base<Derive2<T>,T>{};
int main(){
    //Derive1<int> d1;
    Derive2<int> d2;
}

Demo

有很多与typedefCRTP 相关的问题,但我找不到与我匹配的问题。

【问题讨论】:

  • typedef 不会创建新类型。它仅对类型进行别名。请解释为什么您希望其中任何一个 using 语句起作用
  • 在 CRTP 中你派生一个类...你的“derive1”尝试不使用任何派生,我不清楚你在问什么
  • @AndyG 同意它并没有真正创建一个新类。我希望这些语句能够工作,因为在许多非常简单的情况下,别名和(非常简单的)继承非常可交换并产生相同的结果。不过,我是 C++ 新手。
  • 继承和不继承是完全不同的
  • 优化后你的程序什么都不做……这与任何事情都没有关系

标签: c++ c++14 typedef crtp


【解决方案1】:

这与CRTP无关。

using 创建一个别名;您正在尝试创建一个完全 new独立 类型。

尚不清楚您为什么希望它起作用,或者为什么显示的解决方案不够。

所以,是的,这是不可能的。

【讨论】:

  • 智慧。无量智慧。我爱你(不,这不是性骚扰!)
【解决方案2】:

尝试递归使用Base 的别名将不起作用,因为Base 的每次使用都需要您为其提供2 个模板参数,但您从未这样做,因此排除了这些别名:

template<class T> using Derive1 = Base<Base,T>;
template<class T> using Derive1 = Base<Base<T>,T>;
template<class T> using Derive1 = Base<Base<Base<T>>,T>;

请注意,如果您接受别名的另一个模板参数,则第 3rd 个会成功:

template<class T, class U> using Derive1 = Base<Base<T, U>,T>;

这给我们留下了这个:

template<class T> using Derive1 = Base<Derive1<T>,T>;

这个不起作用的原因是,在 = 运算符的右侧,尚不存在名为 Derive1 的类型,而在左侧,您使用相同的名称作为这样的类型。那么,您是否会遇到与以前相同的问题(递归引用),除了这是不可能的,因为不仅名为 Derive1 的类型不存在用于模板参数中,而且即使它确实存在,编译器也会抱怨你试图重复使用相同的符号。

我怀疑你问的是X-Y Problem,所以如果你提供关于如何使用这些别名的额外上下文,我可以为你提供替代解决方案。

【讨论】:

  • 不,我只是好奇。谢谢。
猜你喜欢
  • 2011-08-25
  • 2021-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
相关资源
最近更新 更多