Mar*_*tin 4 c++ io operator-overloading stream
我经常想将 stl 容器写入 ostream。以下代码工作正常(至少对于向量和列表):
template< typename T ,template<typename ELEM, typename ALLOC=std::allocator<ELEM> > class Container >
std::ostream& operator<< (std::ostream& o, Container<T>const & container){
typename Container<T>::const_iterator beg = container.begin();
while(beg != container.end()){
o << *beg++;
if (beg!=container.end()) o << "\t";
}
return o;
}
Run Code Online (Sandbox Code Playgroud)
现在我想扩展此代码以支持可自定义的分隔符。以下方法显然不起作用,因为运算符应该只采用两个参数。
template< typename T ,template<typename ELEM, typename ALLOC=std::allocator<ELEM> > class Container >
std::ostream& operator<< (std::ostream& o, Container<T>const & container,char* separator){
typename Container<T>::const_iterator beg = container.begin();
while(beg != container.end()){
o << *beg++;
if (beg!=container.end()) o << separator;
}
return o;
}
Run Code Online (Sandbox Code Playgroud)
可以在不诉诸单例或全局变量的情况下实现这样的事情吗?
理想的情况是引入自定义标志或流操纵器,例如std::fixed. 然后就可以写
std::cout << streamflags::tabbed << myContainer;
Run Code Online (Sandbox Code Playgroud)
您可以编写自己的操纵器。basic_ostream提供operator<<采用函数指针的重载(请参阅链接中的 (9)),并调用该函数并将流本身作为参数传递。所以操纵器只是一个函数名称。
或者,操纵器可以是具有合适的 的对象operator<<。这将允许你写,比如说,cout << setSeparator(',') << myContainer;。这里setSeparator是一个带有构造函数的类setSeparator(char)。
最后,ios_base提供xalloc、iword和pword成员,本质上允许将任意信息与特定流实例相关联。这就是您的操纵器与您的通信的方式operator<<(Container)。您确实需要一个全局变量来存储 为您分配的索引xalloc。