2012-02-16 68 views
1

我希望我可以通过使用cout < <来打印set/vector/map的内容。对于设计师来说,这似乎并不困难:假设为T定义了< <,容器的< <可以迭代遍历元素并使用流< <来打印它们。重载<< operator C++ stl containers

有没有简单的方法来打印他们,我不知道?

如果不是,是否有简单的解决方案?我已经在扩展stl类的地方阅读是一个坏主意。是这样吗?为什么?

如何定义类似于重载打印功能的东西? 编辑: 我找了一个递归函数,它可以处理的集装箱的集装箱...... 我认为,不同的人想不同的格式,但覆盖的东西是聊胜于无

+1

[Pretty-print C++ STL containers]的可能重复(http:// stackoverflow。com/questions/4850473/pretty-print-c-stl-containers) – ildjarn 2012-02-16 22:08:45

+0

相当不错的解决方案 – 2012-07-09 09:27:52

回答

3

也许最简单的方式来输出STL容器是

std::copy(cont.begin(), cont.end(), 
      std::ostream_iterator<Type>(std::cout, " ")); 

其中Typecont的元素(例如,如果是cont类型std::vector<int>的然后Type必须int)的类型。

当然,您可以使用任何ostream而不是std::cout

+0

'Type'被称为'container_type :: value_type'。 – ildjarn 2012-02-16 22:11:17

+1

@ildjarn:但是你仍然必须指定'container_type',除非你在一个容器类型为dependend的模板(但是它是'typename container_type :: value_type'),否则很可能包含'Type'无论如何。但是,在C++ 11中,您可以编写'decltype(cont):: value_type'(再次,可能在模板中使用'typename')。 – celtschk 2012-02-16 22:15:05

2

在C++ 11可以使用for基于范围的:

for (auto& i: container) cout << i << " "; 
cout << endl; 
2

最简单的EAY转储容器可能只是使用std::copy()。例如,我通常使用类似这样的东西:

template <typename C> 
std::string format(C const& c) { 
    std::ostringstream out; 
    out << "["; 
    if (!c.empty()) { 
     std::copy(c.begin(), --c.end(), 
      std::ostream_iterator<typename C::value_type>(out, ", ")); 
      out << c.back(); 
    } 
    out << "]"; 
    return out.str(); 
} 

是的,这并不总是工作,但适用于我的需要。这实际上显示了标准库中没有容器输出的问题之一:容器格式化的方式有很多种。更糟的是,格式化的输出应该在事情​​变得真正有趣的地方可读。所有这些都是可行的,但我不知道相应的建议。

0

它显得不那么困难的STL设计者实现:假设< <为T定义,< <的容器可以只通过迭代的元素,并使用ofstream的< <打印出来。

当然这对他们并不难。但是,问问自己:输出格式对每个客户都有意义吗?标准库是关于重用和通用性的。将容器与一些任意的输出格式规则耦合使得它们仅仅为了一些而不那么通用。

因此,推荐的解决方案是提供您自己的operator<<(std::ostream &, T)和/或采用其他通用算法,例如, <algorithms>