请查看下面的两个代码块。在第二个我刚刚将类A放入命名空间。而现在我的脑海里浮现出来试图理解为什么第一个块是好的而第二个块不是。 对不起,主要是代码。你能解释一下为什么吗?我使用的是Microsoft编译器C ++ 14。 请帮忙。
没关系:
#include <iostream>
#include <vector>
#include <iterator>
class A;
class A{};
std::ostream & operator<<(std::ostream & out, const A & a)
{
out << "A";
return out;
}
int main()
{
std::vector<A> v({ A(), A(), A() });
//Prints: "A A A "
std::copy(v.begin(), v.end(), std::ostream_iterator<A>(std::cout, " "));
return 0;
}
这不行:
#include <iostream>
#include <vector>
#include <iterator>
namespace N { class A; }
class N::A{};
std::ostream & operator<<(std::ostream & out, const N::A & a)
{
out << "A";
return out;
}
int main()
{
std::vector<N::A> v({ N::A(), N::A(), N::A() });
//Compiler error C2679:
std::copy(v.begin(), v.end(),
std::ostream_iterator<N::A>(std::cout, " "));
//But this is still ok and prints "A A A" as intended.
//Please, uncomment and try:
/*
for (std::vector<N::A>::iterator it = v.begin(); it != v.end(); ++it)
std::cout << *it << " ";
*/
return 0;
}
答案 0 :(得分:3)
问题是std::copy
找不到operator<<
,没有ADL的帮助。它对您定义的operator<<
一无所知。
因此,您需要将operator<<
移动到声明类A
的同一命名空间中,以使ADL生效,然后找到operator<<
。
namespace N {
class A;
std::ostream & operator<<(std::ostream & out, const A & a);
}
class N::A{};
std::ostream & N::operator<<(std::ostream & out, const N::A & a)
{
out << "A";
return out;
}
注意第一种情况,它运行良好,仍然是因为ADL。只有namesapce是全局命名空间(其中定义了类A
和operator<<
)。