templated circular inheritance
in this code, compiler complain abou开发者_运维百科t 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>
?
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.
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.
精彩评论