简单来说为什么 operator<<
没有过载的basic_ostream
和标准容器如 vector
或pair
。就像 string
一样.
如果有一种标准方法来打印这些对象,那就太容易了。
我很长一段时间想知道为什么这只是出于好奇(并且懒惰地为每个我想快速输出 vector 的小程序编写这样的运算符)。但现在我遇到了一个由此引起的真正的问题:
我正在实现一个库。我有一个异常类 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 container
,key
可以是int
所以一切都很好。对于map like container
key
可以是任何东西,但这要求必须有这样一个operator<<
。但强制用户拥有 operator<<
是有道理的。如果他想扔 OutOfRange
目的。这样可以吗?
真正的困境来自于:现在我实现了 Matrix
抛出 OutOfRange
的类(在同一库中) 。 Key
因为这是 std::pair<int, int>
。所以我有责任提供一个operator<<
对于 std::pair
。但包含定义 Matrix
的 header 似乎不太好。类也会(默默且无关地)带来 operator<<(ostream, std::pair)
的重载。 。如果用户也有这样的过载,则可能会出现冲突。
我觉得如果标准库中有这样的针对标准库中定义的容器的运算符,这一切都可以轻松避免。
我错过了什么吗?我创建消息的方法是否错误?
抱歉,如果我的问题遍布整个宫殿。我试图以一种全面且合乎逻辑的方式将它们联系在一起,不知道我成功了多少。
最佳答案
标准库不重载的原因operator<<
对于容器来说很明显:用户对输出的期望有很大不同(单独考虑分隔符!对于 vector<int>
,空格或逗号可能很好,对于 vector<vector<int>>
换行符可能更好)。不存在“一个正确”的过载。这对于 std::string
当然是不同的它主要不被认为是一个容器,而是一个字符串。
对于你的第二个问题:你可能想重新考虑你的设计并只使用 std::out_of_range
。您还可以针对特定容器专门化您的模板,并使用专门的方法而不是 operator<<
执行打印。 .
另一种行之有效的打印范围的方法是使用 ostream 迭代器:
#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;
}
(此示例代码复制自 cplusplus.com )
关于c++ - 为什么 C++ 标准库没有标准容器的流输出? (以及相关问题),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22392063/