重载 << 运算符以打印 vector<MyClass>

Overloading << operator to print vector<MyClass>

我正在尝试重载 << 运算符以打印包含 Position(向量)类型元素的向量。 我设法为 Position 类型重载了 << 运算符,但我不知道如何为向量重载它。你能帮忙吗?


//position.h

#ifndef POSITION_H    
#define POSITION_H
#include <iostream>    // using IO functions
using namespace std;

class Position {
private:
    int row;
    int column;

public:
    friend ostream& operator<<(ostream& os, const Position& P);
    friend ostream& operator<<(ostream& os, const vector<Position>& VP);
};

#endif

//position.cpp
#include"Position.h"
#include <iostream>    // using IO functions
#include<vector>

ostream& operator<<(ostream& os, const Position& P)
{
    os << '(' << P.row << ',' << P.column << ')' << endl;
    return os;
}
    
ostream& operator<<(ostream& os, const vector<Position>& VP)
{
    Position placeholder;

    for (int i = 0; i != VP.size(); i++)
    {
        placeholder = VP.at(i);
        cout << placeholder << endl;
    }
    return os;
}

int main() 
{
    Position C1(2, 1);
    Position C2(3, 1);
    Position C3(4, 1);

    vector<Position> cans;
    cans.push_back(C1);
    cans.push_back(C2);
    cans.push_back(C3);

    cout << cans;

    system("pause");
}

我确定 Whosebug 上某处有重复项,但我找不到它。我对这个问题有点惊讶,因为我乍一看并没有真正看到一个关键问题。您遇到编译器错误或分段错误了吗?

每次分配给 Placeholder 时,您都会复制一份。这根本没有必要:您可以直接访问索引处的元素。由于您将索引限制为 0size(),您不必担心会变成 out-of-bounds,所以不要使用 .at(i),如果您这样做会抛出异常出界。只需使用 VP[i].

也不是 std::endl 刷新缓冲区,这很慢。 '\n'字符可以实现正常的enter/end-line。

最后,using namespace std; is considered bad practice.

您有多个处理向量元素的选项:

index-based 循环:

for (int i = 0; i != VP.size(); ++i) {
    os << VP[i] << '\n';
}

Iterator-based 循环

for (auto it = cbegin(VP); it != cend(VP); ++it) {
    os << *it << '\n';
}

range-based 循环

for (auto const& el : VP) {
    os << el << '\n';
}

(每个)循环的算法

std::for_each(cbegin(VP), cend(VP),
   [](auto const& el) { os << el << '\n'; });

复制到ostream_iterator

std::copy(cbegin(VP), cend(VP),
    std::ostream_iterator<Position>(os, "\n"));

请注意,您也可以在此处编写 <decltype(VP)::value> 而不是 <Position> 以保持其通用性,但在这种情况下这可能有点矫枉过正。

最后两个具有等效的 C++20 范围:

std::ranges::for_each(VP,
   [](auto const& el) { os << el << '\n'; });
std::ranges::copy(VP,
   std::ostream_iterator<Position>(os, "\n"));

注意: friend ostream& operator<<(ostream& os, const vector<Position>& VP); 不一定是 Position 的朋友!它不需要访问私有成员。