打印用户定义类型的 std::vector
Printing std::vector of a user defined type
请看下面的两个代码块。在第二个中,我刚刚将 class 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;
}
问题是 std::copy
找不到 operator<<
,没有 ADL 的帮助。它对您定义的operator<<
一无所知。
所以你需要将operator<<
移动到class 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 是全局命名空间(其中定义了 class A
和 operator<<
)。
请看下面的两个代码块。在第二个中,我刚刚将 class 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;
}
问题是 std::copy
找不到 operator<<
,没有 ADL 的帮助。它对您定义的operator<<
一无所知。
所以你需要将operator<<
移动到class 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 是全局命名空间(其中定义了 class A
和 operator<<
)。