[英]overload operator<< for std::stack
代码优先:
//.cpp文件
template <typename T>
ostream &operator<<(ostream &os, stack<T> &st)
{
while(! st.empty()) {
os << st.top() << " ";
st.pop();
}
return os;
}
template <typename T>
void stack_sorter(stack<T> &st)
{
cout << st << endl; //no output, st is empty?
//...
}
int main()
{
stack<int> s;
s.push(4);
s.push(3);
s.push(5);
cout << s << endl; //ok
stack_sorter(s);
}
输出:
5 3 4 //this was the output in main, not in stack_sorter
//empty line, but s is not empty, why?
题:
就像我在main中所做的一样,我将s传递给stack_soter(),但是在stack_sorter()中没有输出。 怎么了?
在operator <<
,弹出所有值以输出它们。 所以在cout << s << endl;
,您的堆栈已清空!
一种可能是不通过引用传递,而是堆栈的副本。 但是,这还将复制其中的所有对象。
template <typename T>
ostream &operator<<(ostream &os, stack<T> st) //not &st
{
while(! st.empty()) {
os << st.top() << " ";
st.pop();
}
return os;
}
正如其他人指出的那样, pop_back
使您的输出操作具有破坏性。 根本没有办法在不清空堆栈的情况下读取堆栈的内容……这就是纯堆栈的本质。
同样,对于标准类型重载运算符也是非常差的做法。 由于名称查找的工作方式(ADL,即语言找到要调用的重载函数的方式),因此它的重载函数应与重载类型位于相同的名称空间中。 由于您不能将函数放在std::
,因此第二个最佳选择是全局名称空间,该名称空间会对其造成污染。
但是问题是可以解决的! 幸运的是, stack
提供了继承。 基础容器可用于派生类,并且名为c
。
template< typename value_arg, typename container_arg = std::deque< value_arg > >
struct printable_stack : std::stack< value_arg, container_arg > {
// provide constructors :v( . This is better supported in C++11.
printable_stack( container_arg const &in = container_arg() )
: std::stack< value_arg, container_arg >( in ) {}
friend std::ostream &operator<<
( std::ostream &s, printable_stack const &o ) {
for ( typename container_arg::iterator i = this->c.begin();
i != this->c.end(); ++ i ) {
s << * i << ' ';
}
}
};
此外,拥有专用的类可以使您提供一个额外的成员来容纳分隔符字符串,因此它可以是除简单的空格字符之外的其他内容。
您在ostream &operator<<(ostream &os, stack<T> &st)
循环中对st.pop()
调用将清空堆栈。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.