请看下面的两个代码块。在第二个中,我只是将类 A 放入命名空间中。现在我的头脑沸腾了,试图理解为什么第一个 block 没问题而第二个 block 不行。 对不起,主要是代码。你能解释一下为什么吗?我使用了 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;
}
最佳答案
问题是 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<<
)。
关于c++ - 打印用户定义类型的 std::vector,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39534578/