给定使用CRTP的基类,我正在研究在基模板类中声明一个成员,其中类型取决于派生类。
尽管以下各项按预期工作:
template <class T> class BaseTraits;
template <class T> class Base {
using TypeId = typename BaseTraits<T>::TypeId;
TypeId id;
public:
Base() { id = 123; }
TypeId getId() { return id; }
};
class Derived;
template <> class BaseTraits<Derived> {
public:
using TypeId = int;
};
class Derived : public Base<Derived> {};
int main(int argc, char ** argv) {
Derived foo;
return foo.getId();
}
我想知道是否可以简化实施。我可以在模板中添加第二个模板参数Base
,并使其BaseTraits
更简单甚至摆脱它。但是,以上代码段已经尝试删除第二个模板参数。我正在寻找不涉及的第二个模板参数的解决方案Base
。
我已经尝试过类似以下的内容,但是无法编译:
错误:无效使用不完整类型“派生类”
template <class T> class Base {
using TypeId = typename T::TypeId;
TypeId id;
public:
Base() { id = 123; }
TypeId getId() { return id; }
};
class Derived : public Base<Derived> {
public:
using TypeId = int;
};
int main(int argc, char ** argv) {
Derived foo;
return foo.getId();
}
更新:
Base
必须是模板。是否可以使成员类型直接依赖于派生类?用appart作为用auto
(推断的返回类型)声明的成员函数的结果类型,是不可能的。
因此,像在解决方案中一样使用类型特征是最好的也是唯一的解决方案。
原因是定义派生类时,基类必须是完整类型:编译器必须首先实例化并解析基类定义,然后再解析派生类定义,C ++标准N4140 [derived.class] / 2(粗体是我的):
由base-type-specifier表示的类型应该是不是未完全定义的类的类类型; [...]
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句