【问题标题】:overloading << operator for c++ stl containers为 c++ stl 容器重载 << 运算符
【发布时间】:2012-03-08 08:30:54
【问题描述】:

我希望我可以使用 cout

有没有我不知道的简单打印方法?

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

定义一个类似重载打印函数的东西怎么样? 编辑: 我正在寻找一个递归函数,它可以处理...的容器容器 我同意不同的人会喜欢不同的格式,但可以覆盖总比没有好

【问题讨论】:

标签: c++ stl ofstream


【解决方案1】:

可能最简单的输出 STL 容器的方法是

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

其中Typecont 的元素类型(例如,如果contstd::vector&lt;int&gt; 类型,那么Type 必须是int)。

当然,您可以使用任何 ostream 来代替 std::cout

【讨论】:

  • Type 被称为container_type::value_type
  • @ildjarn:但是你仍然必须指定container_type,除非你在一个容器类型是依赖的模板中(但它是typename container_type::value_type),很可能包含Type 无论如何。但是,在 C++11 中,您可以编写 decltype(cont)::value_type(同样,可能在模板中使用 typename)。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    转储容器最简单的方法可能就是使用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();
    }
    

    是的,这并不总是有效,但可以满足我的需要。这实际上说明了标准库中没有容器输出的问题之一:格式化容器的方式有很多种。更糟糕的是,格式化的输出应该在事情​​变得真正有趣的地方是可读的。所有这些都是可行的,但我不知道有相应的提议。

    【讨论】:

      【解决方案4】:

      stl 设计者实现起来似乎并不难:假设

      当然对他们来说并不难。但是,问问自己:输出的格式对每个客户都有意义吗?标准库是关于重用和通用性的。将容器与一些任意的输出格式规则相结合会降低它们的通用性,这只是为了一些。

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

      【讨论】:

        【解决方案5】:

        你看起来像这样吗?

        #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;
        

        【讨论】:

          【解决方案6】:

          使用 Template 模板参数 很容易,为了使它适用于每个集合,你需要 template 类Xclass...Args 作为模板参数:

          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}
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-12-07
            • 1970-01-01
            • 2018-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-11-15
            相关资源
            最近更新 更多