模板化循环继承
在这段代码中,编译器抱怨 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
因为您的
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.查找“奇怪的重复模板模式”。
您的
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.