使用ostream_iterator和运算符<<显示指针向量

时间:2015-08-19 10:04:49

标签: c++ vector stl

我尝试使用ostream_iteratoroperator <<在对象上显示指针向量。因此,我覆盖了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

3 个答案:

答案 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::bindstd::mem_fn个功能对象。

答案 2 :(得分:1)

考虑到std::ostream_iterator本身使用operator<<作为输出,您可以通过执行另一次重载来轻松解决此问题:

std::ostream& operator<<(std::ostream& os, A const* a)
{
    // Some output of `a` here
    return os;
}