C++ 调用模板函数时出现意外输出

C++ 调用模板函数时出现意外输出,c++,templates,gcc,C++,Templates,Gcc,下面的代码是我正在进行的cpp测验的一部分: #include <iostream> template<typename T> void foo(T) { std::cout << "T" << std::endl;; } struct S { }; template<typename T> void call_foo(T t) { foo(S()); foo(t); } void foo(S) {

下面的代码是我正在进行的cpp测验的一部分:

#include <iostream>

template<typename T>
void foo(T)
{
    std::cout << "T" << std::endl;;
}

struct S
{
};

template<typename T>
void call_foo(T t)
{
    foo(S());
    foo(t);
}

void foo(S)
{
    std::cout << "S" << std::endl;
}

int main()
{
    call_foo(S());
}
#包括
模板
空富(T)
{

std::cout您希望通过参数相关查找相同地解析这两个调用。但是在这种情况下:

foo(S());
foo(t);
第一个
foo
不是从属名称。回想一下,模板中函数的名称查找是通过两种方式完成的:

  • 在函数模板的定义点对所有重载进行常规非限定名称查找
  • 对于依赖名称,依赖参数的查找在模板定义点和实例化点都完成
同样,由于第一个调用不是依赖的,因此只执行常规的非限定名称查找。此时,唯一可见的重载是您先前定义的函数模板
foo
。第二个重载尚不可用,因此不会调用它

§14.6¨9规定:“当寻找一个名称的声明时 在模板定义中,使用通常的查找规则(§3.4.1,§3.4.2) 用于非依赖名称。依赖于模板的名称查找 参数被推迟,直到知道实际的模板参数 (§14.6.2)。”

对foo的第一个调用是非依赖性调用,因此在定义函数模板时会对其进行查询。对于第二个调用,由于依赖于模板参数,因此会将其延迟到模板实例化

template<typename T> void call_foo_function(T t)
{
    foo(S()); // Independent, looks up foo now.
    foo(t); // Dependent, looks up foo later.
}
模板无效调用函数(T)
{
foo(S());//独立,现在查找foo。
foo(t);//依赖,稍后查找foo。
}
在定义函数模板时查找foo时,唯一存在的foo版本是模板化的foo(T)。具体来说,foo(S)还不存在,也不是候选版本

有趣的事情是在VisualStudio中检查您的代码输出,我认为在这种情况下,它将输出您期望的
SS

答案的来源:


不幸的是,我再也找不到答案的确切链接了。

在VS中,答案是SS