为vector <t> </t>重载输出流运算符

时间:2010-11-02 12:28:02

标签: c++ templates vector operator-overloading

重载输出流运算符的推荐方法是什么?以下可以完成。如果运算符&lt;&lt;&lt;&lt;&lt;&lt;&lt;没有为类型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 个答案:

答案 0 :(得分:10)

这就是你想要的:

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

上的std ::

您在[ os << "["之后添加了一个额外的空格。

typename

之前需要std::vector<T>::const_iterator

答案 1 :(得分:7)

你真的尝试过这段代码吗?它通过一个小的调整std::vector<T>::const_iterator在gcc上正常工作,需要声明为typename std::vector<T>::const_iterator

使用std :: copy和std :: ostream_iterator可能会更好。

编辑:类型,依赖类型和类型名称 在评论中不能完全适应这一点,所以这里有(顺便说一句。这是我的理解,我可能会离开一个国家英里 - 如果是这样,请纠正我!)...

我认为最好用一个简单的例子来解释..

假设你有一个函数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"

再次,似乎是自我解释,但是有些nuser出现并且这样做

class IdiotClass
{
  static int bob;
};

现在

foo<IdiotClass>(); // oops, 

你现在拥有的是一个表达式(乘法),因为IdiotClass :: bob解析为非类型!

对于人类来说,很明显这是愚蠢的,但编译器无法区分类型与非类型,默认情况下在C ++中(我认为这是编译器不同的地方),所有限定依赖名称(即T :: 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 :(得分:2)

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

答案 3 :(得分:1)

这在Visual Studio 2003上为我编译。 当然你应该在typename之前使用关键字const std::vector<T> 我不认为inline关键字有意义,恕我直言模板非常接近内联。

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

修改:我已在typename之前添加了std::vector<T>::const_iterator作为Nim建议