如果我不想为此创建一个新容器?
我已经编写了一个代码片段来执行此操作以进行调试。例如:
std::stack<int> s; // works with std::queue also!
s.push(1);
s.push(2);
std::cout << s; // [ 1, 2 ]
请原谅我这个黑客代码!但这是我几个月前写的:
#include <stack>
#include <queue>
#include <ostream>
template <class Container, class Stream>
Stream& printOneValueContainer
(Stream& outputstream, const Container& container)
{
typename Container::const_iterator beg = container.begin();
outputstream << "[";
while(beg != container.end())
{
outputstream << " " << *beg++;
}
outputstream << " ]";
return outputstream;
}
template < class Type, class Container >
const Container& container
(const std::stack<Type, Container>& stack)
{
struct HackedStack : private std::stack<Type, Container>
{
static const Container& container
(const std::stack<Type, Container>& stack)
{
return stack.*&HackedStack::c;
}
};
return HackedStack::container(stack);
}
template < class Type, class Container >
const Container& container
(const std::queue<Type, Container>& queue)
{
struct HackedQueue : private std::queue<Type, Container>
{
static const Container& container
(const std::queue<Type, Container>& queue)
{
return queue.*&HackedQueue::c;
}
};
return HackedQueue::container(queue);
}
template
< class Type
, template <class Type, class Container = std::deque<Type> > class Adapter
, class Stream
>
Stream& operator<<
(Stream& outputstream, const Adapter<Type>& adapter)
{
return printOneValueContainer(outputstream, container(adapter));
}
您可以像任何其他支持的类型一样流式传输
std::stack
和 std::queue
!
您无法迭代堆栈或队列。其实SGI的文档是这么说的(是关于栈的,但是对于队列也是同样的道理):
这个限制是堆栈存在的唯一原因。请注意,任何前插入序列或后插入序列都可以用作堆栈;例如,对于向量,堆栈操作是成员函数 back、push_back 和 pop_back。使用容器适配器堆栈的唯一原因是明确您仅执行堆栈操作,而不执行其他操作。
所以,如果你真的想这样做,你必须清空堆栈(或队列):
std::stack<Whatever> s;
// ...
while(!s.empty())
{
Whatever w = s.top();
std::cout << w;
s.pop();
}
ostream & operator<<(ostream & os, stack<double> my_stack) //function header
{
while(!my_stack.empty()) //body
{
os << my_stack.top() << " ";
my_stack.pop();
}
return os; // end of function
}
/*
using this simple overloaded operator function, you're able to print out all the components of a stack by doing a simple cout << your_stack_name;*/
可以使用递归轻松完成,您只需要知道何时重新添加下一个元素
对于堆栈
void print(stack<char> &s)
{
if(s.empty())
{
cout << endl;
return;
}
char x= s.top();
s.pop();
print(s);
s.push(x);
cout << x << " ";
}
这个是用于队列
void print(queue<char> &s,int num)
{
if(!num)
{
cout << endl;
return;
}
char x= s.front();
s.pop();
cout << x << " ";
s.push(x);
print(s,--num);
}
祝你好运
发布 b/c 我发现这对于调试很有用。 从原始文件弹出到临时文件,然后从临时文件弹回到原始文件:
template <typename T>
void dump_stack(std::stack<T>& stack) {
std::stack<T> temp;
while (!stack.empty()) {
T top = stack.top(); stack.pop();
std::cout << top << " ";
temp.push(top);
}
while (!temp.empty()) {
T top = temp.top(); temp.pop();
stack.push(top);
}
}
我找到了应该适用于 std::stack 的所有实现(IMO)的解决方案,但不幸的是堆栈必须使用 std::vector 而不是队列。
template<typename T>
void printStack(const std::stack<T, std::vector<T>>& s)
{
typedef typename std::stack<T>::const_reference EntryTypeRef;
typedef std::remove_reference_t<EntryTypeRef> EntryType;
for(size_t i=0; i < s.size(); ++i)
{
EntryType* e = &s.top();
cout << *(e-i) << endl;
}
}
std::vector 是动态数组,因此我们可以使用指针 arytmetics。
问题的标记答案假设堆栈有名为“c”的字段,我有另一个解决方案,可以与 std::stack 实现一起使用,该实现将容器作为第一个字段,但其名称并不重要:
template<typename T>
void printStack(const std::stack<T>& s)
{
typedef typename std::stack<T>::container_type Container;
const auto containerPtr = reinterpret_cast<const Container*>(&s);
for(auto e : *containerPtr)
cout << e << endl;
}
试试这个:
template<typename T, typename C>
struct myStack : std::stack<T, C> {
typedef std::stack<T, C> Stack;
using Stack::stack;
using Stack::c;
};
int main()
{
myStack<int, std::deque<int>> s;
s.push(1);
s.push(2);
std::deque<int>::iterator it = s.c.begin();
while (it != s.c.end())
std::cout << ' ' << *it++;
}
这里我们将 std::stack 的底层容器公开为成员 c。
您可以在此处使用答案:https://stackoverflow.com/a/29325258/177259制作一个简单的
get_container
,它公开了保存std::stack
容器适配器的底层容器的底层受保护成员。
诚然,使用了一些黑客技术,但它应该可以工作。 我已经修改了它,因此它返回一个 const 引用到内部容器。
然后你可以轻松地迭代堆栈的内部容器:
#include <iostream>
#include <stack>
#include <vector>
template <class Adapter>
const typename Adapter::container_type & get_container (Adapter &a)
{
struct hack : Adapter {
static typename Adapter::container_type & get (Adapter &a) {
return a.*&hack::c; // access protected member variable
}
};
return hack::get(a);
}
int main () {
std::deque<int> inner{1, 2, 3};
std::stack<int> s{inner};
// for (auto x : s) std::cout << x << " "; // not allowed
for (auto x : get_container(s)) std::cout << x << " ";
// for (auto& x : get_container(s)) x = 42; // not allowed, thankfully
}