模板化循环继承

发布于 2024-10-26 21:31:26 字数 745 浏览 5 评论 0原文

在这段代码中,编译器抱怨 undefined MyClassB,这是可以理解的:

class MyClassA;
class MyClassB;

template <class T> class BaseClass : public T {
};

class MyClassA : public BaseClass<MyClassB> {
};

class MyClassB : public BaseClass<MyClassA> {
};

但在这段代码中,编译成功并且没有抱怨关于 MyClassB

class MyClassA;
class MyClassB;

template <class T> class BaseClass : public T {
};

class MyClassA : public BaseClass<std::vector<MyClassB>> {
};

class MyClassB : public BaseClass<std::vector<MyClassA>> {
};

为什么第二个代码可以编译,因为在构造 std::vector 时尚未定义 MyClassB

in this code, compiler complain about undefined MyClassB, which is understandable :

class MyClassA;
class MyClassB;

template <class T> class BaseClass : public T {
};

class MyClassA : public BaseClass<MyClassB> {
};

class MyClassB : public BaseClass<MyClassA> {
};

but in this code, compile is successful and no complain about MyClassB :

class MyClassA;
class MyClassB;

template <class T> class BaseClass : public T {
};

class MyClassA : public BaseClass<std::vector<MyClassB>> {
};

class MyClassB : public BaseClass<std::vector<MyClassA>> {
};

why the second code compile, since MyClassB is not yet defined when constructing std::vector<MyClassB>?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

站稳脚跟 2024-11-02 21:31:26

因为您的 std::vector 实现允许不完整的类型。这是类模板成员函数的实例化规则的副作用:它们在使用之前不会被实例化。因此,需要它成为完整类型的函数尚未实例化。所以没有错误。

相反,它确实需要是一个完整的类型才能成为基类,因此在这种情况下您会收到错误。


然而,将不完整的类型传递给 std::vector (或任何其他标准库容器)实际上是未定义的行为,并且“它有效”是有效的未定义结果。你不应该这样做。

Because your implementation of std::vector allows an incomplete type. This is a side effect of the instantiation rules of member functions of class templates: they aren't instantiated until they're used. So the functions that do need it to be a complete type aren't instantiated, yet. So no errors.

Contrarily, it does need to be a complete type to be a base class, so you get an error in that case.


However, it's actually undefined behavior to pass an incomplete type to std::vector (or any other standard library container), and "it works" is a valid undefined outcome. You shouldn't do it.

暖树树初阳… 2024-11-02 21:31:26

查找“奇怪的重复模板模式”。

您的 BaseClass 类使用其模板参数作为基类,这需要完整的类型。

代码的第二个版本只是将模板参数传递给另一个模板,在这种情况下,如果第二个模板不执行任何需要完整类型的操作,则允许不完整类型。如果您以任何需要完整类型的方式使用该参数,则也不会被允许。

Lookup the "Curiously Recurring Template Pattern".

Your BaseClass class uses its template argument as a base class, which requires a complete type.

The second version of the code just passes the template argument to another template, an incomplete type is allowed in that case, if the second template doesn't do anything requiring a complete type. If you used the argument in any way that required a complete type, it wouldn't be allowed either.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文