在下面的方案中,operator<<
函数参与重载解析(当它位于全局命名空间中时):
template <typename T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &vec) {
os << '[';
for (const T &val : vec)
os << val << ", ";
return os << "\b\b]";
}
...但在下面,当在名称空间中定义时,它不会:
namespace blah {
template <typename T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &vec) {
os << '[';
for (const T &val : vec)
os << val << ", ";
return os << "\b\b]";
}
}
从main
调用时,如下所示:
int main() {
std::vector<int> vec{5, 4, 3, 6, 4, 3, 5, 6, 8, 1};
std::cout << vec << std::endl;
return 0;
}
...当operator<<
重载在blah
中定义时,编译器无法找到它。
这是怎么回事?
编辑:
当使用范围解析运算符调用重载时,一切都能正常编译:
blah::operator<<(std::cout, vec);
这是为什么呢?
1条答案
按热度按时间omhiaaxx1#
在第一种情况下,使用非限定名称查找和/或ADL(自变量相关查找)查找,其包括声明运算符的全局命名空间。
在第二种情况下,将找不到运算符,因为不考虑名称空间
blah
进行非限定名称查找。您可以使用限定名称,例如:
或者,您可以使用
using
指令将命名空间blah
包含在命名空间集中,以便进行非限定名称查找,如下所示: