c++ - 如何在类型依赖于派生类的基模板类中声明成员?

标签 c++ c++11 templates crtp abstract-base-class

给定一个使用 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 的第二个模板参数的解决方案。

我试过类似下面的方法,但它没有编译:

error: invalid use of incomplete type 'class Derived'

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 必须是模板。
  • 性能是必须的。

最佳答案

是否可以使成员类型直接依赖于派生类?将使用 auto 声明的成员函数的结果类型(推导的返回类型)归类,这是不可能的。

因此,在您的解决方案中使用类型特征是最好且唯一的解决方案

原因是定义派生类时基类必须是完整类型:编译器在解析派生类定义之前必须先实例化并解析基类定义,C++ standard N4140 [derived.class]/2 (粗体是我的):

The type denoted by a base-type-specifier shall be a class type that is not an incompletely defined class;[...]

关于c++ - 如何在类型依赖于派生类的基模板类中声明成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47743338/

相关文章:

c++ 不是类模板

C++模板编译

c++ - 链接器错误 - 其他包含目录问题?

c++ - 没有实例的基类?

c++ - 将构造函数转发给成员对象

c++ - 使用任何参数创建 std::functions 的 unordered_map?

javascript - mustache JS 表 strip 化

c++ - 模板元魔法

c++ - 已知格式文件中的数据排列

c++ - 动态矩阵和 C++ : Segmentation Fault