代码之家  ›  专栏  ›  技术社区  ›  Leonid

重载向量<T>的输出流运算符

  •  14
  • Leonid  · 技术社区  · 14 年前

    建议如何重载输出流运算符?以下可以 完成。如果未为类型T定义运算符<<,则编译将失败。

    template < class T >
    inline std::ostream& operator << (std::ostream& os, const std::vector<T>& v) 
    {
        os << "[";
        for (std::vector<T>::const_iterator ii = v.begin(); ii != v.end(); ++ii)
        {
            os << " " << *ii;
        }
        os << " ]";
        return os;
    }
    

    编辑:它是编译的,问题是不相关的,在名称空间中。谢谢你的帮助。

    4 回复  |  直到 14 年前
        1
  •  7
  •   Nim    14 年前

    你真的试过这个密码吗?它在gcc上运行良好,只需稍作调整 std::vector<T>::const_iterator typename std::vector<T>::const_iterator

    使用std::copy和std::ostream_迭代器可能会更好。

    编辑: 不能把这些都写进评论里,所以就这样(顺便说一句,这是我的理解,我可能会离开一个国家英里-如果是这样,请纠正我!)...

    假设有一个函数foo

    template <typename T>
    void foo()
    {
      T::bob * instofbob; // this is a dependent name (i.e. bob depends on T)
    };
    

    看起来不错,通常你可以这样做

    class SimpleClass
    {
      typedef int bob;
    };
    

    foo<SimpleClass>(); // now we know that foo::instofbob is "int"
    

    同样,似乎是不言而喻的,但是有些用户出现了,并且这样做了

    class IdiotClass
    {
      static int bob;
    };
    

    foo<IdiotClass>(); // oops, 
    

    现在你得到的是一个表达式(乘法)作为idotClass::bob解析为一个非类型!

    全部的 从属名称 非类型 . 到 明确地 typename 关键字-

    template <typename T>
    void foo()
    {
      typedef typename T::bob *instofbob; // now compiler is happy, it knows to interpret "bob" as a type (and will complain otherwise!)
    };
    

    typedef . 即

    template <typename T>
    void foo()
    {
      typedef typename T::bob local_bob;
    };
    

    这更清楚了吗?

        2
  •  10
  •   Jason Iverson    14 年前

    这就是你想要的:

    template < class T >
    std::ostream& operator << (std::ostream& os, const std::vector<T>& v) 
    {
        os << "[";
        for (typename std::vector<T>::const_iterator ii = v.begin(); ii != v.end(); ++ii)
        {
            os << " " << *ii;
        }
        os << "]";
        return os;
    }
    

    ostream

    你在 [ 在里面 os << "[" .

    你需要 typename std::vector<T>::const_iterator

        3
  •  2
  •   Grimeh smartnut007    8 年前
    template<typename T>
    std::ostream& operator<<(std::ostream& s, std::vector<T> t) { 
        s << "[";
        for (std::size_t i = 0; i < t.size(); i++) {
            s << t[i] << (i == t.size() - 1 ? "" : ",");
        }
        return s << "]" << std::endl;
    }
    
        4
  •  1
  •   Stephane Rolland    14 年前

    这是在visual studio 2003上为我编译的。 当然你应该用关键字 typename const std::vector<T> 我不认为 inline 关键字有意义,IMHO模板非常接近内联。

    #include <ostream>
    #include <vector>
    #include <iostream>
    
    template < class T >
    std::ostream& operator << (std::ostream& os, typename const std::vector<T>& v) 
    {
        os << "[ ";
        for (typename std::vector<T>::const_iterator ii = v.begin(); ii != v.end(); ++ii)
        {
            os << " " << *ii;
        }
        os << "]";
        return os;
    }
    
    void Test()
    {
        std::vector<int> vect;
        vect.push_back(5);
        std::cerr << vect;
    }
    

    类别名 也是在 std::vector<T>::const_iterator