稍后定义的重载函数的名称查找
Name lookup for overloaded functions defined later
我注意到在依赖稍后定义的函数时,函数查找的奇怪行为:
#include <iostream>
template <typename T>
void foo(const T&)
{
std::cout << "Basic" << std::endl;
}
template <typename T>
void bar()
{
T x;
foo(x);
}
void foo(const int& x)
{
std::cout << "int:" << x << std::endl;
}
int main()
{
bar<int>();
}
输出:
Basic
出于某种原因,我希望在bar
内部使用foo
来找到它下面的重载。将foo
的重载移动到bar
之上会使输出成为所需的int:0
(或者只是写一个声明)。
这种相同的行为似乎不适用于重载二进制运算符:
#include <iostream>
struct Foo {} foo;
template <typename T>
void operator<<(const Foo&, const T&)
{
std::cout << "Basic" << std::endl;
}
template <typename T>
void bar()
{
T x;
foo << x;
}
void operator<<(const Foo&, const int& x)
{
std::cout << "int:" << x << std::endl;
}
int main()
{
bar<int>();
}
输出:
int:0
我有两个问题,第一个问题是:为什么行为是这样的,为什么操作员过载不同?第二个问题是:如果我有一个命名函数(就像我使用foo
一样),是否有一种方法可以编写函数bar
,从而发现稍后在翻译单元中声明的过载foo
?
欢迎来到最著名的两相查找和怪异规则的世界。
我确信运算符和函数的情况没有区别,只是因为你又使用了一个参数。尝试一下,如果在第一个版本中还添加了另一个具有结构Foo的参数,会发生什么。。。
分两个阶段查找意味着在编译模板时,对于依赖名称,它会四处查找并记住可见函数集。在你的情况下,什么也找不到。然后在实例化上下文中有另一个查找,遵循ADL(参数相关查找)规则。仅此而已。这意味着首先要收集参数的"关联名称空间",然后在这些名称空间中寻找更多的候选者。
在您的情况下,唯一的参数是int,并且它没有关联的名称空间,因此不会再次找到任何内容。在第二种情况下,您还拥有拖动::的Foo,并且您的操作符位于:中。
相关文章:
- 递归ASMVisitor 和查找函数调用站点
- C++ - 查找函数无法在子字符串上执行
- 查找函数是否为常量
- GDB 如何查找函数退出的位置
- 查找函数在unordered_map中的工作方式是搜索键值
- 在 C++ <algorithm>中查找函数
- 错误:二进制表达式的操作数无效(映射使用查找函数错误)
- 哪个查找规则阻止编译器查找函数
- 在C++中查找函数的调用方(Visual Studio)
- 关于获取行和字符串查找函数的问题
- 查找函数在失败结果中应该返回什么
- 如何使用调用和别名指令在 llvm 字节码中查找函数名称
- std::字符串类查找函数不返回预期结果.我可能用错了
- 在成对向量中查找函数时出错
- 从堆栈指针中查找函数参数值
- 如何定义查找函数
- 如何查找函数是否可重入
- 在c++中查找函数
- GNU g++ 4.9.2 查找函数调用的编译错误
- 使用GDB查找函数对应的内存地址/调试