C++ 重载向量的输出流运算符<;T>;
建议用什么方法重载输出流操作符?以下是无法做到的。如果运算符C++ 重载向量的输出流运算符<;T>;,c++,templates,vector,operator-overloading,C++,Templates,Vector,Operator Overloading,建议用什么方法重载输出流操作符?以下是无法做到的。如果运算符 内联std::ostream&operator这是我在VisualStudio2003上为自己编译的。 当然,您应该在const std::vector 而且我认为inline关键字没有意义,IMHO模板真的很接近内联 #include <ostream> #include <vector> #include <iostream> template < class T > std::o
内联std::ostream&operator这是我在VisualStudio2003上为自己编译的。 当然,您应该在
const std::vector
而且我认为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::ostream&operator您真的尝试过这个代码吗?它在gcc上运行良好,只需稍加调整std::vector::const_迭代器
,需要声明为typename std::vector::const_迭代器
使用std::copy和std::ostream_迭代器可能会更好
编辑:类型、从属类型和类型名
无法将所有内容都放在评论中,所以这里(顺便说一句,这是我的理解,我可能会离开一个国家英里——如果是的话,请纠正我!)
我认为最好用一个简单的例子来解释这一点
假设你有一个函数foo
template <typename T>
void foo()
{
T::bob * instofbob; // this is a dependent name (i.e. bob depends on T)
};
打电话
foo<SimpleClass>(); // now we know that foo::instofbob is "int"
现在
即使它是typedef
,这也适用。i、 e
template <typename T>
void foo()
{
typedef typename T::bob local_bob;
};
模板
void foo()
{
typedef typename T::bob local_bob;
};
这更清楚了吗?模板
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;
}
std::ostream&operator这就是您想要的:
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&operator有人能告诉我,为什么我不能标记这段代码?因为SO使用了一个修改版本的“markdown”。为格式化代码缩进4个空格。<代码>警告:与未签名的INT/C++ >相比,签入:(内联与模板化正交)。模板不需要“KONRAD <代码> INSLINE < /COD>。ODR允许省略。”“关键字typename只能应用于限定名称,但这些名称不需要依赖。”.C++03还强制“关键字typename只能在模板声明和定义中使用。”“,但C++0x将删除它。所有这些都表明,std::vector
肯定是一个依赖名称。但这里仍然不需要typename
,因为编译器可以在解析时查找std::vector
,并查看它是一个类模板(从而知道std::vector
是一个类型)他实际上想写的是consttypename…
或typename…const
而不是typename const…
,虽然最后一个在语法上是非法的。@Konradvector
没有限定符,但是std::vector
是。关于内联的内容,请参见最后的3.2项目符号列表(我现在这里没有标准),其中提到了类内联函数和函数/类模板。为什么在通用向量的情况下,std::copy
是一种更好的流式输出方法?使用std::copy
时,应该编写一条专用的长线来流式输出向量。但是,使用输出流操作符更容易:std::解决原始问题后,它是否可以不使用typename进行编译。在这种情况下,指定typename
是否有任何用处,即使它确实可以编译,但有轻微的类型被误解的风险?@Leonid,是的,如果有人解释依赖名称的概念,那就太好了。@Leonid,在平凡的vecto中上面的例子,同意STD:复制操作看起来是冗长的,但是现在考虑你决定改变格式化,你希望它在某些情况下被一个“a”分隔开来,而另一个则用一个“全局”来分隔。operator@Leonid,至于你的第二点,如果你的编译器很高兴,你也很高兴你永远不必在另一个编译器中重新编译你的代码,那么我就不麻烦了;但是为了一个关键词“typename”,如果您需要在编译器之间移动,那么您可以省去一些头疼的事情,尝试理解由于省略它而得到的相当详细的编译器错误消息!这是您的职责…您可以详细说明名称空间问题及其解决方案吗?在全局名称空间中这样的重载函数不会当参数类型是来自std,并且不能将其放入std时,由ADL执行und。如何解决它?C++11语法:for(auto&i:vec){}
make codeshorter@Charles编译(const auto&i:vec)
时应使用。
foo<IdiotClass>(); // oops,
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!)
};
template <typename T>
void foo()
{
typedef typename T::bob local_bob;
};
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;
}
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;
}