模板聲明與模板定義的匹配程度如何?如果「模板名稱引用了相同的模板和[...]」(14.4 [temp.type]),我在標準模板標識中發現了一些文字, p1)但我找不到模板名稱或模板名稱指向相同模板的定義。我不確定我是否在正確的軌道上,因爲我還沒有足夠好地分解語法以確定模板的定義/聲明是否包含9模板ID ,或者只是使用模板。模板定義如何與模板聲明相匹配?
例如,以下程序正常工作。
#include <iostream>
template<typename T>
T foo(T t);
int main() {
foo(1);
}
template<typename T>
T foo(T t)
{ std::cout << "A\n"; return 0; }
如果我改變我的模板定義的名稱顯然不再指同一模板使用模板參數的方式,連接失敗。
#include <iostream>
template<typename T>
T foo(T t);
int main() {
foo(1);
}
template<typename T>
int foo(T t) { std::cout << "A\n"; return 0; }
// or
template<typename T>
struct identity {
typedef T type;
};
template<typename T>
typename identity<T>::type
foo(T t) { std::cout << "A\n"; return 0; }
接下來,如果我的模板定義移動到另一個翻譯單位,爲我實現C++(MSVC 11測試版)的程序,無論我怎麼說的各類作品。
//main.cpp
template<typename T>
T foo(T t);
int main() {
foo(1);
}
//definition.cpp
#include <iostream>
template<typename T>
struct identity {
typedef T type;
};
template<typename T>
typename identity<T>::type
foo(T t) { std::cout << "A\n"; return 0; }
template int foo<int>(int);
或
//definition.cpp
#include <iostream>
template<typename T>
int foo(T t) { std::cout << "A\n"; return 0; }
template int foo<int>(int);
或者即使定義不是一個模板都:
//definition.cpp
#include <iostream>
int foo(T t) { std::cout << "A\n"; return 0; }
顯然鏈接是成功的,因爲簽名/重整名稱是一樣的,不管被實例化以創建符號的模板。我覺得這個不確定的行爲,因爲我違反了:一類模板的
§14.1 [溫度] P6
函數模板,類模板的成員函數或靜態 數據成員應除非 對應的專業化被明確實例化(14.7.2)在 某些翻譯單元中;否則在每個翻譯 定義它隱式實例化(14.7.1)的單位;不需要診斷。
但隨後說我嘗試把模板的定義在第二個翻譯單元,幷包括一個顯式實例在兩個位置之一,以滿足這些要求:
#include <iostream>
template<typename T>
T foo(T t) { std::cout << "A\n"; return 0; }
// Location 1
template<typename T>
int foo(int t) { std::cout << "B\n"; return 0; }
// Location 2
哪些規則關於明確實例化引用的模板的歧義?將它放在位置1會導致實例化正確的模板,並將該定義用於最終的程序,同時將它放在位置2處實例化另一個模板,並導致我認爲在上面14.1 p6下未定義的行爲。
另外的兩個模板定義的隱式實例挑選第一個模板不管是什麼,因此它似乎爲消除歧義模板的規則是在這種情況下不同:
#include <iostream>
template<typename T>
T foo(T t) { std::cout << "A\n"; return 0; }
template<typename T>
int foo(int t) { std::cout << "B\n"; return 0; }
int main() {
foo(1); // prints "A"
}
此次前來的原因提問者發現,一個向前聲明凡達有關this question
template<typename T>
T CastScriptVarConst(const ScriptVar_t& s);
不能充當多個模板定義聲明:
template<typename T>
typename std::enable_if<GetType<T>::value < SVT_BASEOBJ,T>::type
CastScriptVarConst(const ScriptVar_t& s) {
return (T) s;
}
template<typename T>
typename std::enable_if<!(GetType<T>::value < SVT_BASEOBJ)
&& std::is_base_of<CustomVar,T>::value,T>::type
CastScriptVarConst(const ScriptVar_t& s) {
return *s.as<T>();
}
我想更好地理解模板定義和聲明之間的關係。
拿起一份「C++模板:完整指南」的完整故事。是的,它比標準更容易消化...實際上很多;) – 0xC0000022L 2012-03-07 19:21:59