使用 std::ostream 打印矢量

Use of std::ostream for Printing Vectors

我是 C++ 的新手,我正在尝试打印出 Institutions 的向量,这是我创建的一种对象。对象的创建和我的程序的其余部分运行得很好,但是当我尝试打印出向量时,“<<”给出了一个错误,显示 "operand types are std::ostream".

void PrintVector(const vector<Institution> &institutions)
{
    for (int x = 0; x < institutions.size; x++)
    {
        cout << institutions.at(x) << endl;
    }
}

我曾尝试研究 std::ostream 是什么或它的作用,但由于我对 C++(或一般编程)知之甚少,所以我无法理解其中的任何内容解释它的网站。为什么通常的 "cout <<" 在这种情况下不起作用?任何人都可以向我解释这是什么意思,或者是否有其他方法可以打印出不需要这个的矢量?

感谢任何帮助,谢谢。

您可能希望为您的 class 机构重载 ostream 运算符 (<<): https://msdn.microsoft.com/en-us/library/1z2f6c2k.aspx

ostream& operator<<(ostream& os, const Institution& inst)
{
    os << inst.foo; /* some member variable */;
    return os;
}

问题在于 C++ ostreamcout 是)无法打印出 Institution 对象。您将不得不按照另一个答案 (https://msdn.microsoft.com/en-us/library/1z2f6c2k.aspx?f=255&MSPPError=-2147217396) 中发布的 link 中的描述,在我们的 Institution 中重载 operator<< 函数,以使其正常工作。

您必须为您的 class:

提供 operator <<
std::ostream& operator << (std::ostream& os, const Institution& institution)
{
    os << institution.getValue();
    // ...
    return os;
}

operator<< 被重载以允许输出内置类型,如 intdouble。但是您需要通过再次重载告诉编译器如何输出您的 class Institution

std::ostream& operator<<(std::ostream& os, const Institution& inst) {
    os << inst.name(); // or something
    return os;
}

您显示的代码至少有两个问题。

1)

for (int x = 0; x < institutions.size; x++)

std::vector::size() 是一个 class 方法,一个函数。它不是 class 成员。这应该是:

for (int x = 0; x < institutions.size(); x++)

2)

cout << institutions.at(x) << endl;

不幸的是,std::ostream 对您的 Institution 一无所知 class。您将需要实现一个 class 方法,例如 display(),它将 assemble class 内容的可打印表示形式,并将其写入输出流。因此,例如,如果 class 包含两个 std::string,称为 name,并且 address:

class Institution {

// ...

public:

      void display(std::ostream &o)
      {
           o << name << std::endl << address << std::endl;
      }
// ...
};

... 或者,以您希望显示 class 实例的任何格式样式。那么:

for (int x = 0; x < institutions.size(); x++)
     institutions.at(x).display(std::cout);

3)

好吧,你的代码有一个额外的问题。它实际上是用几十年前过时的过时 C++ 方言编写的。无论您使用什么教科书来学习 C++,您都需要抛弃它,并选择一本本世纪编写的教科书,它将教您现代 C++。在现代 C++ 中,这变得更具可读性:

for (const auto &institution:institutions)
     institution.display(std::cout);

这里的答案都是正确的。我将为显示问题提供一个略有不同的答案,因为这是一个反复出现的问题。你可以做的是定义一个抽象 class,我们称之为 IDisplay,它声明一个纯虚函数 std::ostream& display(std::ostream&) const 并声明 operator<< 作为友元。然后,每个要显示的 class 都必须继承自 IDisplay 并因此实现 display 成员函数。这种方法重用了代码并且非常优雅。示例如下:

#include <iostream>

class IDisplay
{
private:
    /**
    * \brief Must be overridden by all derived classes
    *
    * The actual stream extraction processing is performed by the overriden
    * member function in the derived class. This function is automatically
    * invoked by friend inline std::ostream& operator<<(std::ostream& os,
    * const IDisplay& rhs).
    */
    virtual std::ostream& display(std::ostream& os) const = 0;

public:
    /**
    * \brief Default virtual destructor
    */
    virtual ~IDisplay() = default;

    /**
    * \brief Overloads the extraction operator
    *
    * Delegates the work to the virtual function IDisplay::display()
    */
    friend inline
    std::ostream& operator<<(std::ostream& os, const IDisplay& rhs)
    {
        return rhs.display(os);
    }
}; /* class IDisplay */

class Foo: public IDisplay
{
public:
    std::ostream& display(std::ostream& os) const override 
    {
        return os << "Foo";
    }
};

class Bar: public IDisplay
{
public:
    std::ostream& display(std::ostream& os) const override 
    {
        return os << "Bar";
    }
};

int main() 
{
    Foo foo;
    Bar bar;
    std::cout << foo << " " << bar;    
}

Live on Coliru