为什么C ++标准库没有标准容器的流输出? (及相关问题)

时间:2014-03-13 22:10:33

标签: c++

简单地说明operator<< basic_ostream和标准容器(例如vectorpair)的重载原因。就像string一样。

如果有一种标准方法可以打印这些对象,那就太容易了。


我很长一段时间想知道为什么这只是一种好奇心(为每一个我希望快速输出矢量的小程序编写这样的运算符的懒惰)。但是现在我遇到了由此造成的真正的问题

我正在实施一个库。我有一个例外类utils::exception::OutOfRange。构造函数将表示超出范围的key的对象作为参数。我使用stringstream(和其他东西)来创建(全面的)错误消息:

template <class Key>
inline OutOfRange::OutOfRange(const Key &key) : Exception(2) {
  //just the interesting part (a simplified version):
  string_stream message;
  message << "accessed at key/index '"<< key; // <-- there must be an operator<< for key
}

对于vector like containerkey可以是int,所以一切都很好。对于map like containerkey可以是任何内容,但这需要必须存在operator<<。但是如果用户希望抛出operator<<对象,强迫用户拥有OutOfRange是有意义的。那可以吗?

真正的困境来自于:现在我实现了Matrix类(在同一个库中)抛出OutOfRange。此Keystd::pair<int, int>。因此,我有责任为operator<<提供std::pair。但是,包含定义Matrix类的标题也会带来(无声地和无关地)operator<<(ostream, std::pair)的重载。如果用户也有这样的过载,则可能会出现冲突。

如果在标准库中为标准库中定义的容器中存在此类运算符,我觉得这一切都很容易避免。

我错过了什么吗?我创建错误的方法是错误的吗?

道歉,如果我的问题遍布整个宫殿。我试图以圆润和合乎逻辑的方式将它们捆绑在一起,不知道我成功了多少。

2 个答案:

答案 0 :(得分:3)

标准库没有为容器重载operator<<的原因显而易见:用户对输出的期望大不相同(单独考虑分隔符!对于vector<int>,空格或逗号可能是好的,对于vector<vector<int>>换行可能会更好)。没有“一个正确的”超载。这对于std::string来说当然是不同的,std::out_of_range主要不被认为是一个容器,而是一个字符串。

对于您的第二个问题:您可能需要重新考虑您的设计并使用operator<<。您还可以为特定容器专门设置模板,并使用专门方法而不是#include <iostream> // std::cout #include <iterator> // std::ostream_iterator #include <vector> // std::vector #include <algorithm> // std::copy int main () { std::vector<int> myvector; for (int i=1; i<10; ++i) myvector.push_back(i*10); std::ostream_iterator<int> out_it (std::cout,", "); std::copy ( myvector.begin(), myvector.end(), out_it ); return 0; } 执行打印。

打印范围的另一种成熟方法是使用ostream迭代器:

{{1}}

(此示例代码是从cplusplus.com复制的)

答案 1 :(得分:1)

正在尝试写出密钥,负责决策/设计的后果。

问题是&#34;只打印出foo&#34;类型的对象。 没有单一答案。也许对我来说,一对给出经度和纬度(因此应该以度,分,秒和小数分数显示),对于你来说,是一对数字,在笔记本中用两位小数写。这只是一个简单的案例,一些复杂的类怎么样?将公共成员写成名称/值?受保护的私人物品?静态成员?以某种方式标记基类?