重载解析、名称查找和函数指针



我有一个查找和重载分辨率行为不同的情况:

  • 对于用户定义的类vs内置类型vsstd::string
  • 用于直接调用函数指针调用

我无法弄清楚标准的哪些确切部分证明了这些差异。

请考虑以下 C++11 代码:

#include <iostream>
#include <string>
using namespace std;
struct Test1 {};
struct Test2 {};
template<typename T>
int f(T t) { return 0; }
int f(Test1 t) { return 10; }
int f(int y) { return 20; }
template<typename T>
int use1() { return f(T()); }
template<typename T>
int use2() { auto fp = static_cast<int(*)(T)>(&f); return (*fp)(T()); }
int f(Test2 t) { return 30; }
int f(string s) { return 40; }
int f(double y) { return 50; }
int main() {
cout << "use1<float>:  " << use1<float>()  << endl;
cout << "use1<Test1>:  " << use1<Test1>()  << endl;
cout << "use1<int>:    " << use1<int>()    << endl;
cout << "use1<Test2>:  " << use1<Test2>()  << endl;
cout << "use1<string>: " << use1<string>() << endl;
cout << "use1<double>: " << use1<double>() << endl;
cout << endl;
cout << "use2<float>:  " << use2<float>()  << endl;
cout << "use2<Test1>:  " << use2<Test1>()  << endl;
cout << "use2<int>:    " << use2<int>()    << endl;
cout << "use2<Test2>:  " << use2<Test2>()  << endl;
cout << "use2<string>: " << use2<string>() << endl;
cout << "use2<double>: " << use2<double>() << endl;
return 0;
}

输出是(与 g++ 6.3 和 clang++5.0.0 主干相同(:

use1<float>:  0
use1<Test1>:  10
use1<int>:    20
use1<Test2>:  30
use1<string>: 0
use1<double>: 0
use2<float>:  0
use2<Test1>:  10
use2<int>:    20
use2<Test2>:  0
use2<string>: 0
use2<double>: 0

问题:

  1. 为什么use1<string>use1<Test2>不同?两种类型都声明为"在顶部",两个 f(( 重载都在底部声明。
  2. 为什么use1<Test2>use1<double>不同?对应的 f(( 重载在相邻的行上,内置类型的处理有什么特别的吗?
  3. 为什么use1<Test2>use2<Test2>不同?指向正在使用的函数2的指针的类型似乎与正在使用的调用上下文1匹配。

两阶段名称查找。在定义use1点,通过正常查找可以看到三个f重载。在实例化时,可能会发现其他重载 - 但只能通过依赖于参数的查找。Test2位于全局命名空间中,因此 ADL 可以找到f(Test2);而string在命名空间std中,因此 ADL 找不到f(string)(显然不在命名空间std中(。double没有关联的命名空间,因此 ADL 根本不会启动。

use2中,f不是一个依赖名称,因此根本不执行第二阶段查找 - 只考虑在定义点可见的重载。

相关内容

  • 没有找到相关文章

最新更新