【发布时间】:2017-12-10 20:52:14
【问题描述】:
给定一个使用 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 更简单,甚至去掉它。然而,上面的 sn-p 已经是尝试删除第二个模板参数了。我正在寻找不涉及 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();
}
更新:
- 我仅限于 c++14。
-
Base必须是模板。 - 性能是必须的。
【问题讨论】:
-
好吧,您的第二个示例不起作用,因为在完全声明之前,您不能将类用作模板参数。你想通过这些课程实现什么?您确定它们需要模板化吗?
-
@MarošBeťko 你非常可以,此时它是一个不完整的类,你可以使用一个不完整的类作为模板参数。
-
@MarošBeťko 我希望 Base 声明一个只有 Derived 知道类型的成员。是的,我需要使用模板,至少对于 Base。
-
您真的需要
id成为Base的成员吗?你也可以让它成为Derived的成员...... -
不幸的是,是的。事实上,我需要一个数组。
标签: c++ c++11 templates crtp abstract-base-class