原來的問題已經細化了。
給定一個名為main.cpp如下的源代碼檔案:
#include <string>
extern template class std::basic_string<char>;
template<typename T>
struct A
{
T n = {};
T get() const
{
return n;
}
};
extern template struct A<int>;
int main()
{
auto a = A<int>{}.get(); // undefined reference to `A<int>::get() const'
auto b = static_cast<int>(std::string{}.size()); // ok
return a b;
}
我的期望:
請注意,源代碼有extern template class std::basic_string<char>但沒有template class std::basic_string<char>。
因此,編譯器不會實體化類std::basic_string<char>,那么g main.cpp將導致在線鏈接錯誤std::string{}.size()上線A<int>{}.get()。
我觀察到的:
g main.cpp上線就OK了std::string{}.size()。在線演示
為什么 extern template class 技術不能按預期作業?
uj5u.com熱心網友回復:
它不起作用至少有兩個原因。
一沒有禁止extern template由實作宣告的庫類和函式模板實體化。gcc并libstdc 做到這一點。
$ g -E main.cpp | grep 'extern.*string'
extern template class basic_string<char>; // <-- from the library
extern template class basic_string<wchar_t>; // <-- from the library
extern template class std::basic_string<char>; // <-- your line
標準庫實作包含顯式實體化定義(您可以挖掘源代碼)。
兩個作為顯式實體化宣告主題的物體,并且以其他方式使用會導致翻譯單元中的隱式實體化的物體應是程式中某處顯式實體化定義的主題;否則程式格式錯誤,不需要診斷[ temp.explicit ]。
NDR 的一個可能的理由是不extern template應該阻止不涉及鏈接的行內和其他用途。事實上, with-O2 A::get是行內的,程式構建得很好。沒有任何成熟的技術可以迫使該程式無論如何被拒絕。它可以因聯結器錯誤而被拒絕,但不需要出現聯結器錯誤。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/358158.html
上一篇:為什么我不能將lambdas作為默認值分配給函式引數?
下一篇:如何呼叫具有特定大小的視圖?
