Я понял, что явный запрос на создание экземпляра также автоматически создаст экземпляр всех элементов базового класса, но при создании этого кода с помощью Visual Studio 2008 или 2010 я получаю linker error: unresolved external symbol "public: void Base<int>::foo(int)"
.
Обратите внимание, что добавление вызова 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)"
}
Edit:
Похоже, что в стандарте говорится, что только члены класса получают экземпляр с помощью явного создания экземпляра класса, поэтому ошибка компоновщика оправдана в моем примере.
Обратите внимание, что класс определяется классом-head {member-specification} и "Спецификация участника в определении класса объявляет полный набор членов класса, ни один член не может быть добавлен в другое место". Таким образом, члены находятся только между фигурными фигурными скобками {}, а члены базового класса public не становятся членами производного класса, они просто доступны из производного класса или объектов производного класса.
Мой единственный оставшийся вопрос заключается в том, почему стандарт указывает, что явное инстанцирование шаблона класса только создает экземпляры, а не элементы базовых классов? Я предполагаю, что это позволяет больше контролировать то, что получает явным образом экземпляр где-то. Кто-то, кто использует явные экземпляры класса шаблонов, скорее всего, будет иметь определения базового класса в другом файле, чем определения производного класса, и будет явно создавать экземпляры каждого отдельно.