for*_*818 6 c++ operator-overloading ostream
我有以下代码:
#include <iostream>
#include <vector>
namespace X {
std::ostream& operator<<(std::ostream& os,const std::vector<double>& v){
for (int i=0;i<v.size();i++){os << v[i] << " ";}
return os;
}
namespace Y {
struct A {std::vector<double> x;};
std::ostream& operator<<(std::ostream& os,const A& a){
os << a.x << std::endl;
return os;
}
}
}
using namespace X;
int main(int argc, char** argv) {
std::vector<double> v(10,0);
std::cout << v << std::endl;
Y::A a;
std::cout << a << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
第一个重载是有效的,但第二个没有.由于某种原因,它找不到第一个.我收到错误:
no match for 'operator<<' (operand types are 'std::ostream
{aka std::basic_ostream<char>}' and 'const std::vector<double>')
os << a.x << std::endl;
^
Run Code Online (Sandbox Code Playgroud)
我不明白为什么我会收到这个错误.例如,像这样的东西似乎是完全有效的:
namespace A {
void foo(){}
namespace B {
void bar(){foo();}
}
}
Run Code Online (Sandbox Code Playgroud)
但是,修复上述问题的唯一方法是将第二个重载也放在X中.为什么不能将它与结构(即X :: Y)放在同一个命名空间中?
在参数相关查找(或 Koenig 查找)中,编译器将每个参数的父作用域中声明的所有符号添加到可见范围。
即使Y是 的“子命名空间” X,它们在 方面也不相关ADL。第一个参数是在std::命名空间中定义的类型,而第二个参数是本地符号(在与函数本身相同的命名空间中定义)。
请注意,由于上述原因,您很可能会在此行中收到另一个错误:
std::cout << v << std::endl;
Run Code Online (Sandbox Code Playgroud)
当编译器将无法找到operator<<重载的 for std::vector<double>(因为它位于内部namespace X)。
为了解决这个问题,您可以使用:
using X::operator<<
Run Code Online (Sandbox Code Playgroud)
内部namespace Y或移动该过载。
如果您想知道为什么foobar示例有效:那是因为ADL(参数依赖查找)是关于函数参数的范围,而不是函数本身。在foobar代码中,ADL不适用。
| 归档时间: |
|
| 查看次数: |
713 次 |
| 最近记录: |