我尝试使用ostream_iterator
和operator <<
在对象上显示指针向量。因此,我覆盖了operator <<
。我总是得到矢量元素地址的问题。如何使迭代器打印实际值?我需要专门化吗?
class A {
private:
double x;
long y;
public:
A(long xx, double yy) :x(xx), y(yy){};
~A();
void Display();
};
template<typename T>
std::ostream &operator <<(std::ostream &os, const std::vector<T> &v) {
using namespace std;
copy(v.begin(), v.end(), ostream_iterator<T>(os, "\n"));
return os;
}
int main()
{
std::vector<A*> aVect;
FillA(aVect);
cout << accountVect;
return 0;
}
//
output
00657990
006579D0
00657A48
答案 0 :(得分:5)
您可以为operator<<
写一个A*
重载,但首先取消引用指针会更好一些,例如:
template<typename T>
std::ostream &operator <<(std::ostream &os, const std::vector<T *> &v) {
std::transform(v.begin(), v.end(),
ostream_iterator<T>(os, "\n"),
[](T const *ptr) -> T const& { return *ptr; }
);
return os;
}
然后为operator<<
编写通常的A
重载。
注意 - 正如@WhozCraig在评论中提到的那样,你的现有代码不会打印向量元素的地址,它会按照你的要求打印向量元素,而元素是一个地址。如果可以的话,最简单的解决办法就是首先使用vector<A>
。
但是,我假设您需要保留vector<A*>
并想要打印已取消引用的A
个对象。
另外,我坚持使用原始模板,但不完全清楚非模板operator<<(ostream&, vector<A*> const &)
是否更清晰。
答案 1 :(得分:3)
我有点修改了你的代码:
#include <functional>
class A {
public:
A(){ x = 5; y = 5;}
A(long xx, double yy) :x(xx), y(yy){};
~A();
void Display() {
std::cout << "X: " << x << " | Y: " << y << std::endl;
}
double x; // made this public just not to create an accessor
long y;
};
template<typename T>
std::ostream &operator <<(std::ostream &os, const std::vector<T*> &v) {
std::transform(v.begin(), v.end(), std::ostream_iterator<decltype(T::x)>(os, "\n"), [](const T* t){return t->x;});
// or use A::Display() method with std::bind
std::for_each(v.begin(), v.end(), std::bind(&A::Display, std::placeholders::_1));
// or with std::mem_fn
std::for_each(v.begin(), v.end(), std::mem_fn(&A::Display));
return os;
}
int main()
{
std::vector<A*> aVect = {new A, new A, new A};
std::cout << aVect;
return 0;
}
所以第一个问题是你需要正确专业化:
std::ostream &operator <<(std::ostream &os, const std::vector<T*> &v) {
而不是
std::ostream &operator <<(std::ostream &os, const std::vector<T> &v) {
这是因为你有指针数组,但你当前的专业化适用于vector的非指针对象。
接下来,我已修改了您的std::copy
来电,因为在您为班级operator<<
提供A
重载之前,该调用无效。所以,我已将其更改为std::transform
,以便能够输出您的值。
UPD ,这里有一种方法可以使用A::Display()
方法和std::for_each
算法,并使用std::bind
或std::mem_fn
个功能对象。
答案 2 :(得分:1)
考虑到std::ostream_iterator
本身使用operator<<
作为输出,您可以通过执行另一次重载来轻松解决此问题:
std::ostream& operator<<(std::ostream& os, A const* a)
{
// Some output of `a` here
return os;
}