Инстанцируют ли явные экземпляры шаблонов классов C ++ зависимые базовые классы?
Я предполагал, что явный запрос на создание экземпляров автоматически создаст все экземпляры базового класса, но я получаюlinker error: unresolved external symbol "public: void Base<int>::foo(int)"
при создании этого кода с использованием Visual Studio 2008 или 2010.
Обратите внимание, что добавление вызоваfoo()
внутриbar()
заставляет компилятор создаватьBase<int>::bar()
и сборка завершается успешно, поэтому кажется, что компилятор имеет всю необходимую информацию для создания экземпляраfoo()
.
Очевидно, в явном видеBase<int>
В source.cpp сборка успешна, но кажется глупым необходимость явно создавать экземпляры любых зависимых базовых классов всякий раз, когда явно создается производный класс.
Это нормально? Я не мог найти то, что стандарт говорит относительно этой проблемы.
header.h
template<typename T>
class Base {
public:
void foo();
};
template<typename T>
class Derived : public Base<T> {
public:
void bar();
};
source.cpp
#include "header.h"
template<typename T>
void Base<T>::foo() { }
template<typename T>
void Derived<T>::bar() {
// this->foo(); // adding this forces instantiation of foo()???
}
template class Derived<int>;
main.cpp
#include "header.h"
int main() {
Derived<int> d;
d.foo(); // Linker Error: unresolved external symbol "public: void Base<int>::foo(int)"
}
Редактировать:
Похоже, что Стандарт говорит, что только члены класса создаются с помощью явного создания экземпляра класса, поэтому ошибка компоновщика оправдана в моем примере.
Обратите внимание, что класс определяетсяclass-head {член-спецификация} и «Спецификация члена в определении класса объявляет полный набор членов класса; ни один член не может быть добавлен в другом месте». Таким образом, члены находятся только между фигурными скобками {}, и открытые члены базового класса не становятся членами производного класса, они просто доступны из производного класса или из объектов производного класса.
Мой единственный оставшийся вопрос - почему Стандарт определяет, что явное создание экземпляра шаблона класса только создает экземпляры членов, а не членов базовых классов? Я предполагаю, что это позволяет лучше контролировать то, что и где явно создается. Тот, кто использует явные экземпляры класса шаблона, скорее всего, будет иметь определения базового класса в файле, отличном от определений производного класса, и будет явно создавать каждое из них отдельно.