我想通了顯式實例請求將自動實例的所有基類成員還可以,但使用Visual Studio 2008或2010顯式實例化C++類模板實例化相關基類?
注意添加到foo()
內bar()
呼叫強制編譯器建設這個代碼時,我得到一個linker error: unresolved external symbol "public: void Base<int>::foo(int)"
實例化Base<int>::bar()
並且構建成功,所以似乎編譯器具有實例化foo()
所需的全部信息。
明顯地,在source.cpp中明確實例化Base<int>
可以使構建成功,但顯式實例化派生類時需要顯式實例化任何相關基類似乎很愚蠢。
這是正常的嗎?我無法找到關於這個問題的標準。
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 {member-specification}定義的,「類定義中的成員規範聲明瞭該類的全部成員;沒有成員可以添加到別處。因此,成員只在大括號{}之間,並且公共基類成員不會成爲派生類的成員,它們只能從派生類或派生類的對象訪問。
我唯一剩下的問題是爲什麼標準指定類模板的顯式實例化只實例化成員而不是基類的成員?我的猜測是,這可以更好地控制哪些地方顯式實例化。某個使用顯式模板類實例的人很可能將基類定義放在與派生類定義不同的文件中,並且會分別明確地實例化每個實例。
是否爲基類的派生觸發器實例化添加顯式構造函數?我懷疑編譯器正在嘗試不做更多的工作。有一個構造函數可能會讓它意識到它需要構建Base,並且可能會觸發它。另外,你有沒有嘗試gcc或其他編譯器? – 2010-09-15 00:00:41
添加一個帶或不帶參數且帶或不帶關鍵字「explicit」的構造函數都不會觸發基類foo()的實例化,但是從派生成員bar()調用foo()會觸發隱式實例化。 – JohnPS 2010-09-15 00:54:54