C++:如何将标准库容器输出或使用cout打印到控制台?

5

如何使用C++方式将C++标准库容器的内容打印或输出到控制台以查看其内容?

另外,为什么C++库实际上没有为您重载<<运算符?背后有什么历史原因吗?


1
遍历元素并打印每个元素?也许您可以展示一下您所询问的示例。 - Retired Ninja
你是在打印想要获取特定值的对象,还是在打印简单数据类型? - Hayden
1
你可以尝试使用一个漂亮的打印机(pretty printer):http://louisdx.github.io/cxx-prettyprint/ - chris
有相当多类似的现有问题,要求和答案在不同的复杂度和完整性水平上...例如:http://stackoverflow.com/questions/4850473/pretty-print-c-stl-containers?lq=1 - Tony Delroy
@RetiredNinja:我只是想要一种好的方式来打印对象,类似于在Python中可以使用“print list”或“print set”。不需要排序。 - hlin117
3个回答

4

重载 ostreamoperator<< 是一个不错的选择。以下是一种可能的实现:

template <class container>
std::ostream& operator<<(std::ostream& os, const container& c)
{
    std::copy(c.begin(),
              c.end(),
              std::ostream_iterator<typename container::value_type>(os, " "));
    return os;
}

那么你可以简单地写成以下内容:
std::cout << SomeContainer << std::endl;

以下是其他非常好的解决方案:美化C++ STL容器


1
最简单的方法是使用基于范围的for语句。例如:
#include <iostream>
#include <string>
#include <vector>
#include <iterator>

template <class Container>
std::ostream & display( const Container &container, 
                        const char *s = " ",
                        std::ostream &os = std::cout )
{
    for ( const auto &value : container )
    {
        os << value << s;
    }

    return os;
}

int main()
{
    int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    std::vector<int> v( std::begin( a ), std::end( a ) );

    display( a, "; " );
    std::cout << std::endl;

    display( v );
    std::cout << std::endl;

    return 0;
}

程序输出是:
0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 
0 1 2 3 4 5 6 7 8 9 

然而,更灵活的方法是使用标准算法std::copy,你可以自己设置显示范围并使用反向迭代器。此外,你也可以编写函数以获取附加信息。

为什么C++库没有为你实际重载<<运算符?

因为任何用户都可以使用自己的方法输出容器,正如你可以从我的演示程序的输出中看到的那样。事实上,容器是一个用户定义的类,应该由用户重载运算符<<。 std::string和std::bitset有例外,但是字符串和位集像基本类型一样输出为一个实体而不带有中间分隔符。


我觉得C++应该为operator<<提供一些标准实现。Python至少为其标准数据结构提供了这样的功能。 - hlin117

0

为了多样性,可以制作一个适配器,类似于:

template< typename T >
struct SequencePrinter
{
    const T& t;
    // ...
};
template< typename T >
SequencePrinter<T> sequence_printer(const T&);
template< typename T >
ostream& operator<<(ostream&, SequencePrinter<T>);
int main() {
    vector<int> v;
    // ...
    cout << sequence_printer(v) << endl;
}

这允许使用通常的<<符号,但不会尝试强制规定序列中<<的特定含义。当然,它也可以被相当灵活地配置。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接