Reputation: 1
I am thinking that the best way to return the second element of a stack without popping the stack is to create a function is to uses peek but peek returns the top element. How would I override peek so that it returned the second element, or use peek in some other fashion to accomplish my goal?
Upvotes: 0
Views: 3422
Reputation: 7400
just use std::vector instead.
std::vector<int>numbers;
numbers.push_back(1);
numbers.push_back(2);
numbers.push_back(3);
int secondElem = *(nums.end() - 2);
cout << secondElem << endl;
prints 2
Upvotes: 0
Reputation: 20063
According to the C++ Standard std::stack
contains a protected member variable for the container named c
. Knowing this and using a little bit of magic you can gain access to it with a pointer to this member variable. Once you have access to the underlying container (std::deque
by default) you can access the contained data.
template<class T /* value type */, class C /* container */>
typename std::stack<T, C>::container_type& GetContainer(std::stack<T,C>& adapter)
{
struct AdapterAccessor : std::stack<T, C>
{
static std::stack<T, C>::container_type& Get(std::stack<T, C>& adapter)
{
return adapter.*&AdapterAccessor::c;
}
};
return AdapterAccessor::Get(adapter);
}
This works because although AdapterAccessor
does not have direct access to the contents of adapters
it does have indirect access via the pointer-to-member.
You can also make it usable with other container adapters.
template <template<class, class> class Adapter, class T, class... Args>
typename Adapter<T, Args...>::container_type&
GetContainer(Adapter<T, Args...>& adapter)
{
struct AdapterAccessor : Adapter<T, Args...>
{
static Adapter<T, Args...>::container_type& Get(Adapter<T, Args...>& adapter)
{
return adapter.*&AdapterAccessor::c;
}
};
return AdapterAccessor::Get(adapter);
}
Example usage:
int main()
{
std::stack<char> st;
st.push('1');
st.push('2');
st.push('3');
st.push('4');
auto& contents = GetContainer(st);
std::cout << contents[0] << std::endl;
std::cout << contents[3] << std::endl;
std::cout << contents[1] << std::endl;
std::cout << contents[2] << std::endl;
}
Upvotes: 1
Reputation: 2845
This is java like pseudo algorithm. What you do is use a variable to store the top of the stack (pop if it exists), use another to store the second element of the stack (peek if it exists), push the top element back and then return the second element.
Object obj = stack.empty() ? null : stack.pop();
if(obj == null)
return null;
Object ret = stack.empty() ? null : stack.peek();
stack.push(obj);
return ret;
But everything depends on how the stack is implemented. In C++, you'll have to do something like this.
if(stck.size() < 2) throw "Stack has no second element!";
Object obj = stck.top();
stck.pop();
Object ret = stck.top();
stack.push(obj);
return ret
Upvotes: 1
Reputation: 1509
Not to be restricted in "Stack". It is an abstract datatype, so you can define the datatype of yourself. If you just don't want to define datatype and want to use some functions of stack. I advise you to define a function of yourself(like the answer of Sudo Andrew). But it seems far-fetched and not like stack.
Upvotes: 0
Reputation: 92
I'm not sure if it is possible, since a stack is based off of the principle last in first out. All you have is a pointer to the stack, and from there you can pop off from the top of the stack, but you cannot pop off within the stack. The only way I can think of to do it would be to create a function like.
object returnSecond(stack<object> a){
a.pop();
return a.top();
}
or a more general one function like
object peekN(stack<object> a, int n){
for(int i = 0;i<n;i++){
a.pop();
}
return a.top();
}
Upvotes: 0