【发布时间】:2012-03-08 08:30:54
【问题描述】:
我希望我可以使用 cout
有没有我不知道的简单打印方法?
如果没有,是否有简单的解决方案?我在一些地方读到扩展 stl 类是一个坏主意。是这样吗,为什么?
定义一个类似重载打印函数的东西怎么样? 编辑: 我正在寻找一个递归函数,它可以处理...的容器容器 我同意不同的人会喜欢不同的格式,但可以覆盖总比没有好
【问题讨论】:
我希望我可以使用 cout
有没有我不知道的简单打印方法?
如果没有,是否有简单的解决方案?我在一些地方读到扩展 stl 类是一个坏主意。是这样吗,为什么?
定义一个类似重载打印函数的东西怎么样? 编辑: 我正在寻找一个递归函数,它可以处理...的容器容器 我同意不同的人会喜欢不同的格式,但可以覆盖总比没有好
【问题讨论】:
可能最简单的输出 STL 容器的方法是
std::copy(cont.begin(), cont.end(),
std::ostream_iterator<Type>(std::cout, " "));
其中Type 是cont 的元素类型(例如,如果cont 是std::vector<int> 类型,那么Type 必须是int)。
当然,您可以使用任何 ostream 来代替 std::cout。
【讨论】:
Type 被称为container_type::value_type。
container_type,除非你在一个容器类型是依赖的模板中(但它是typename container_type::value_type),很可能包含Type 无论如何。但是,在 C++11 中,您可以编写 decltype(cont)::value_type(同样,可能在模板中使用 typename)。
在 C++11 中,您可以使用基于范围的for:
for (auto& i: container) cout << i << " ";
cout << endl;
【讨论】:
转储容器最简单的方法可能就是使用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();
}
是的,这并不总是有效,但可以满足我的需要。这实际上说明了标准库中没有容器输出的问题之一:格式化容器的方式有很多种。更糟糕的是,格式化的输出应该在事情变得真正有趣的地方是可读的。所有这些都是可行的,但我不知道有相应的提议。
【讨论】:
stl 设计者实现起来似乎并不难:假设
当然对他们来说并不难。但是,问问自己:输出的格式对每个客户都有意义吗?标准库是关于重用和通用性的。将容器与一些任意的输出格式规则相结合会降低它们的通用性,这只是为了一些。
因此,推荐的解决方案是提供您自己的operator<<(std::ostream &, T) 和/或采用其他通用算法,如在例如<algorithms>.
【讨论】:
你看起来像这样吗?
#include <iostream>
#include <set>
template <typename T>
std::ostream& operator<< (std::ostream& os, const std::set<T>& s)
{
for( auto i: s ) {
os << i << " ";
}
return os;
}
那么你可以这样使用它:
std::set<int> my_set = { 11, 12, 13 };
std::cout << my_set << std::endl;
【讨论】:
使用 Template 模板参数 很容易,为了使它适用于每个集合,你需要 template
template<class T, template<class, class...> class X, class... Args>
std::ostream& operator <<(std::ostream& os, const X<T, Args...>& objs) {
os << "{";
bool commoFlag = false;
for (auto const& obj : objs) {
os << (commoFlag ? ", " : "") << obj;
commoFlag = true;
}
os << "}";
return os;
}
vector<float> f_vec{ 1.3f , 5.134f, 5.78f };
list<char> c_lst{ 'F','O', 'M', 'S', 'A' };
set<int> i_st{ 17,14, -70 };
std::cout << f_vec << std::endl;
std::cout << c_lst << std::endl;
std::cout << i_st << std::endl;
输出:
{1.3, 5.134, 5.78}
{F, O, M, S, A}
{-70, 14, 17}
【讨论】: