重载输出流运算符的推荐方法是什么?以下可以不完成。如果运算符<<<<<<<没有为类型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;
}
编辑:它确实编译,问题无关,并且在命名空间中。感谢您的帮助。
答案 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
您在[
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建议