テンプレート定義がテンプレート定義とどのくらい正確に一致していますか?私は標準でいくつかのテキストを見つけましたテンプレートのID "テンプレート名 [...]は同じテンプレートと[...]"(14.4 [temp.type] p1)しかしテンプレート名の定義が見つからないまたはテンプレート名が同じテンプレートを参照しています。とにかく文法をよく解読していないので、のテンプレート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; }
テンプレート定義でテンプレートパラメータを使用する方法を変更すると、その名前は明らかに同じテンプレートを参照しなくなり、リンクは失敗します。私はC++(MSVC 11ベータ版)の私の実装のために、別の翻訳単位にテンプレート定義を移動した場合
#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; }
は次に、プログラムは関係なく、私は種類が言うどのように動作しません。
//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 [TEMP]を
P6関数テンプレート、クラステンプレートのメンバ関数、またはクラステンプレートの静的 データメンバをしなければならない。私は違反してるので、私はこの未定義の動作を考えます 対応する特殊化が明示的にインスタンス化されていない限り(14.7.2)、 一部の翻訳単位で暗黙的にインスタンス化される単位(14.7.1)で定義されます。診断は必要ありません。
しかし、その後、私は第2の翻訳単位でテンプレートの定義を入れ、そして2つのいずれかの場所での明示的なインスタンスを含むことにより、これらの要求を満たすためにしようと言う:
#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"
}
理由:それはテンプレートの曖昧さを解消するためのルールのように思えるので、一方
2つのテンプレート定義の暗黙のインスタンス生成は、このような状況が異なっている、どんなの最初のテンプレートを選びません
0123:アップは、質問者は、単一の前方宣言template<typename T>
T CastScriptVarConst(const ScriptVar_t& s);
は、複数のテンプレート定義の宣言として行動することができなかったことを発見しthis questionに関連しています
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++ Templates:The Complete Guide"のコピーを手に入れてください。そして、はい、それは標準よりも消化可能です...実際はたくさんあります;) – 0xC0000022L