Operator< & lt;重载隐藏其他
Operator<< overloading hides other
我有一个奇怪的运算符<<超载的问题,我找不到一个原因。下面的代码是该问题的摘录。这段代码在VS2015, g++ 5.4.0和clang 3.8.0下无法编译,所以我认为这不是编译器的错误。
#include <iostream>
#include <stdexcept>
inline std::ostream &operator<<(std::ostream &o, const std::exception &ex) {
o << ex.what();
return o;
}
namespace ns {
struct Struct { int m; };
inline std::ostream &operator<<(std::ostream &o, const Struct &s) {
o << s.m;
return o;
}
void fn() {
std::cout << Struct{ 1 } << std::endl;
try {
throw std::runtime_error("...");
} catch (std::exception &ex) {
std::cout << ex << std::endl;
}
}
}
int main() {
return 0;
}
编译器找不到操作符<<对于std::exception ("std::cout <<前女友& lt; & lt;std:: endl;"失败)。特别让我困惑的是,如果我:
- 删除重载操作符<<用于Struct或
- 如果我将所有代码从命名空间ns移动到全局命名空间
代码编译。这种行为的原因是什么?
您所看到的是c++中名称查找规则的结果。这就是为什么不建议在您编写的类类型中至少没有一个操作数的情况下提供操作符重载。
换句话说,你应该设计你的代码,使它没有operator<<(std::ostream&, std::exception)
,因为它会无意中被其他operator<<
隐藏在命名空间中。
此行为对所有函数都是相同的,操作符名称也不例外。
另一种解决方案是将using ::operator<<;
放在定义更多operator<<
过载的任何名称空间中。
完整的名称查找规则集有点复杂。非限定函数名查找的要点是:
- 根据参数查找名称。
- 非adl查找查找名称。
- 将(1)和(2)的结果结合起来产生查找集。
在您的代码o << s.m
中,步骤1在类std::ostream
中搜索成员operator<<
,在命名空间std
中搜索非成员operator<<
。
步骤2搜索:
-
ns::operator<<
的主体,以防在该函数中有任何函数声明!(没有找到) - 命名空间
ns
,直到并包括发生调用的函数点。(发现ns::operator<<
)
关键是,一旦通过非adl查找找到ns::operator<<
,非adl查找过程就会停止——它不会继续搜索更多的封闭命名空间来查找更多的重载。
最终查找集是(1)和(2)的并集,即std::ostream::operator<<
、std::operator<<
和ns::operator<<
。然后重载解析只对这些限定名的重载进行。
下面是相同原理的一个更简单的例子,没有添加ADL集的干扰:
void bar(int);
namespace N
{
void bar(char const *);
void nfunc() { bar(1); }
}
没有ADL,因为参数1
不是类类型。非adl非限定查找找到N::bar
并停止。不考虑::bar
。代码编译失败
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- GL_SHADERSTORAGE_BUFFER位置是否与其他着色器位置冲突
- 为什么我不能在 C++ 中的特定函数重载中调用同一函数的任何其他重载?
- 在其他文件中创建类时在 c++ 项目中不起作用
- 类与私有变量的其他类之间的线程安全性
- 结构和双指针隐藏在其他结构中,多层混淆
- 只知道运行时的数据类型.如何将数据详细信息隐藏到使用它们的其他类
- 是否可以从其他线程隐藏qt小部件窗口
- 为什么使用std::swap不会在外部范围中隐藏其他交换函数
- 隐藏 QWidget,防止其他 QWidget
- 如何在不擦除 Windows 上C++中的其他属性的情况下隐藏/取消隐藏文件
- 扩展类以进行调试:公共API、隐藏实现或其他什么
- 将其他运算符隐藏一段时间
- Operator< & lt;重载隐藏其他
- 如何对其他用户隐藏一个秘密
- 在g++中我可以访问哪些其他隐藏变量(使用宏预先定义的)?
- 如何向其他子系统隐藏类
- C++ - 如何隐藏其他应用程序的窗口