我想构建以下类。基类定义要实现的功能,Derived实现这个接口(interface)。
template <class T, class V>
class IBase
{
public:
virtual void foo(const typename V::t_args&) =0;
};
template<class T>
struct T_args
{
T z;
};
class Derived : public IBase<double, Derived>
{
public:
typedef T_args<double> t_args;
Derived() {}
void foo(const t_args& x)
{ /* do some stuff */ }
};
编译器提示 Derived 类型不完整;我不明白为什么。 有没有办法让这个类结构正确?
我被迫使用 c++98 进行编码,但我对 c++11 及更高版本的任何解决方案都感兴趣。
最佳答案
在您的基模板类中:
virtual void foo(const typename V::t_args&) =0;
这是在引用其 V
模板参数的一些名为 t_args
的内部类或类型。引用类成员时,类的定义必须完整(以便弄清楚 t_args
是什么)。您正在尝试按如下方式使用此模板类:
class Derived : public IBase<double, Derived>
您正在为您的 V
传递 Derived
,但是它的类定义不完整。如果模板基类只引用了它的V
参数,一般是“ok”的。然而,您的模板要求其模板参数类型是完整的,因为它需要知道 t_args
到底是什么,并且您的派生类在完全定义之前是不完整的。但是在它的基类被完全定义之前,它不能被完全定义。有点像先有鸡还是先有蛋。
没有针对这种循环引用的交 key 解决方案。唯一可以做的就是重构类,所以你的“参数”类型是一个独立的类,而不是派生类。
关于c++ - 涉及 CRTP 和内部类型的类特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51210197/