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

Fly*_*yer 5 c++ templates crtp abstract-base-class c++11

给定使用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();
}
Run Code Online (Sandbox Code Playgroud)

我想知道是否可以简化实施。我可以在模板中添加第二个模板参数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();
}
Run Code Online (Sandbox Code Playgroud)

更新:

  • 我仅限于c ++ 14。
  • Base 必须是模板。
  • 性能是必须的。

Oli*_*liv 5

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

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

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

基类型说明符表示的类型应是不是不完全定义的类的类类型;[...]