[英]c++ template - type/value mismatch - Instantiate base class template with a type dependent on derived class
[英]Do Explicit Instantiations of C++ Class Templates Instantiate Dependent Base Classes?
我認為顯式實例化請求也會自動實例化所有基類成員,但是在使用 Visual Studio 2008 或 2010 構建此代碼時出現linker error: unresolved external symbol "public: void Base<int>::foo(int)"
.
請注意,在bar()
中添加對foo()
的調用會強制編譯器實例化Base<int>::bar()
並且構建成功,因此編譯器似乎具有實例化foo()
的所有必要信息。
顯然,在 source.cpp 中顯式實例化Base<int>
可以使構建成功,但是在顯式實例化派生類時需要顯式實例化任何依賴基類似乎很愚蠢。
這是正常的嗎? 我找不到標准關於這個問題的內容。
頭文件.h
template<typename T>
class Base {
public:
void foo();
};
template<typename T>
class Derived : public Base<T> {
public:
void bar();
};
源碼.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>;
主文件
#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 }定義,並且“類定義中的成員規范聲明了該類的完整成員集;不能在其他地方添加任何成員。” 所以成員只在花括號 { } 之間,公共基類成員不會成為派生類的成員,它們只能從派生類或派生類的對象訪問。
我剩下的唯一問題是為什么標准規定類模板的顯式實例化只實例化成員而不是基類的成員? 我的猜測是,這可以更好地控制在何處顯式實例化的內容。 使用顯式模板類實例化的人很可能會將基類定義與派生類定義放在不同的文件中,並且會分別顯式實例化每個。
標准說
類模板特化的顯式實例化意味着實例化其所有以前未明確專門化的包含顯式實例化的轉換單元的成員。
換句話說,它並沒有強制要求依次顯式地實例化基類。 它將導致它們的隱式實例化,它們不會預先實例化它們的成員定義。 標准中的一些丑陋小故障是關於某個文本是否表示“成員”意味着“直接”或“繼承”成員,因為對於編寫標准措辭的人來說,這通常似乎是“顯而易見的”,但對於一個人讀它。 C ++ 0x添加了一些說明(它在顯式實例化聲明和C ++ 03沒有的定義之間也有區別,但即使忽略它,C ++ 0x措辭還包含更多的洞察力):
命名類模板特化的顯式實例化也是其每個成員(不包括從基類繼承的成員)的相同類型(聲明或定義)的顯式實例化,該實例之前未明確專門用於包含該類的轉換單元。顯式實例化,除非如下所述。 [注意:此外,它通常是關於類的某些依賴於實現的數據的顯式實例化。 - 結束說明]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.