Pretty-print C++ STL containers

前端 未结 10 1777
谎友^
谎友^ 2020-11-21 07:39

Please take note of the updates at the end of this post.

Update: I have created a public project on GitHub for this library!


10条回答
  •  自闭症患者
    2020-11-21 08:05

    Here is a working library, presented as a complete working program, that I just hacked together:

    #include 
    #include 
    #include 
    
    #include 
    
    // Default delimiters
    template  struct Delims { static const char *delim[3]; };
    template  const char *Delims::delim[3]={"[", ", ", "]"};
    // Special delimiters for sets.                                                                                                             
    template  struct Delims< std::set > { static const char *delim[3]; };
    template  const char *Delims< std::set >::delim[3]={"{", ", ", "}"};
    
    template  struct IsContainer { enum { value = false }; };
    template  struct IsContainer< std::vector > { enum { value = true }; };
    template  struct IsContainer< std::set    > { enum { value = true }; };
    
    template 
    typename boost::enable_if, std::ostream&>::type
    operator<<(std::ostream & o, const C & x)
    {
      o << Delims::delim[0];
      for (typename C::const_iterator i = x.begin(); i != x.end(); ++i)
        {
          if (i != x.begin()) o << Delims::delim[1];
          o << *i;
        }
      o << Delims::delim[2];
      return o;
    }
    
    template  struct IsChar { enum { value = false }; };
    template <> struct IsChar { enum { value = true }; };
    
    template 
    typename boost::disable_if, std::ostream&>::type
    operator<<(std::ostream & o, const T (&x)[N])
    {
      o << "[";
      for (int i = 0; i != N; ++i)
        {
          if (i) o << ",";
          o << x[i];
        }
      o << "]";
      return o;
    }
    
    int main()
    {
      std::vector i;
      i.push_back(23);
      i.push_back(34);
    
      std::set j;
      j.insert("hello");
      j.insert("world");
    
      double k[] = { 1.1, 2.2, M_PI, -1.0/123.0 };
    
      std::cout << i << "\n" << j << "\n" << k << "\n";
    }
    

    It currently only works with vector and set, but can be made to work with most containers, just by expanding on the IsContainer specializations. I haven't thought much about whether this code is minimal, but I can't immediately think of anything I could strip out as redundant.

    EDIT: Just for kicks, I included a version that handles arrays. I had to exclude char arrays to avoid further ambiguities; it might still get into trouble with wchar_t[].

提交回复
热议问题