C++ 模板定义如何与模板声明匹配?

C++ 模板定义如何与模板声明匹配?,c++,templates,C++,Templates,模板声明与模板定义的匹配程度如何?我在标准中找到了一些关于模板ID引用相同函数的文本,如果“它们的模板名称[…]引用相同的模板和[…]”(14.4[temp.type]p1),但我找不到模板名称的定义或模板名称引用相同模板时的定义。我不确定自己的思路是否正确,因为我没有很好地破译语法,无法判断模板id是模板定义/声明的一部分,还是仅仅是模板的使用 例如,以下程序工作正常 #include <iostream> template<typename T> T foo(T t

模板声明与模板定义的匹配程度如何?我在标准中找到了一些关于模板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; }
#包括
模板
T foo(T T),;
int main(){
傅(1),;
}
模板
T-foo(T-T)
{std::cout

我想更好地理解模板定义和声明之间的关系。

好的,让我们从头开始。模板的“模板名称”是被模板化的函数或类的实际名称;也就是说,在

template<class T> T foo(T t);
第7段继续将这两个定义扩展到整个函数模板。两个匹配的函数模板(在名称、范围和模板参数列表中)如果它们还具有等效的返回类型和参数类型,则为等效函数;如果它们仅具有等效的返回类型和参数类型,则为等效函数。请看第二个示例,这两个函数仅在功能上等效:-

template<typename T>
T foo(T t);

template<typename T>
typename identity<T>::type foo(T t);
为函数模板执行重载解析的整个过程太长,此处无法描述。如果您感兴趣,请阅读第14.8.3节,并提出更多问题:-)

为完整的故事挑选一份“C++模板:完整指南”。是的,它比标准更容易理解……实际上很多;)
//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; }
#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
#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"
}
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>();
}
template<class T> T foo(T t);
template<int A, int B>
void f(array<A + B>);
template<int T1, int T2>
void f(array<T1 + T2>);
template<int A, int B>
void f(array< mpl::plus< mpl::int<A>, mpl::int<B> >::value >);
template<typename T>
T foo(T t);

template<typename T>
typename identity<T>::type foo(T t);
/* Template definition. */
template<typename T>
T foo(T t)
{ ... }

/* Specialization, OK in itself. */
template< >
int foo(int t)
{ ... }

/* Explicit instantiation, OK in itself. */
template< >
int foo(int t);
template<typename T>
T f(T f)
{ ... }

template< >
int f(int);

void g(void)
{ f(3); }
template<typename T>
T f(T f)
{ ... }

template f(int);

void g(void)
{ f(3); }
template<typename T>
T f(T f)
{ ... }

void g(void)
{ f(3); } // Implicitly specializes int f(int)

template< >
int f(int) // Too late for an explicit specialization
{ ... }
template<typename T>
T foo(T t) { ... }

template<typename T>
int foo(int t) { ... }
f<int>(3); // ambiguous
f<string>(3); // can only be the second one