我的代码如下:
#include<iostream>
#include <vector>
using namespace std;
template<class T>
class Stack
{
private:
vector<T> stack;
public:
T Pop()
{
if (stack.size()!=0)
{
T temp;
temp=stack[stack.size()-1];
stack.erase(stack.begin()+stack.size()-1);
return temp;
}
else
//return nothing
^^^^^^^^^^^^^^^^
//How i can do above by code
}
在pop功能中:我想要stack.size==0
;弹出功能什么都不返回
我怎么做?
答案 0 :(得分:5)
这基本上是一个如何处理non-total functions的问题 - 不一定为所有可能的输入定义的函数。有很多方法可以实现,但它们都不是类型安全的:
有两个独立的函数可用于检索和删除堆栈的顶部元素,非常类似于std::stack::top()
和std::stack::pop()
。
使用引用参数并返回bool
,指示是否返回了元素:
bool pop(T& value) {
if (stack.empty())
return false;
value = stack.back();
stack.pop_back();
return true;
}
来电者可写:
T value;
if (stack.pop(value)) {
use(value);
}
返回默认构造的T
实例。这要求T
是可默认构造的,这已由某些std::vector
成员函数强加。
抛出异常,记录违反前提条件。
保持弹出空堆栈的行为未定义。
我建议#1,#2或#3,具体取决于偏好以及最适合周围代码的内容。
答案 1 :(得分:2)
您可能仍希望以与分割为std::stack::top
和std::stack::pop
的std :: stack相同的方式执行操作。您不希望pop
返回值。
以下是http://cpptruths.blogspot.com.au/2005/10/why-does-stdstackpop-returns-void.html
的解释http://www.sgi.com/tech/stl/stack.html解释
[3]有人可能想知道为什么pop()返回void而不是value_type。也就是说,为什么必须使用top()和pop()来检查和删除顶部元素,而不是将两者组合在一个成员函数中?事实上,这种设计有充分的理由。如果pop()返回顶部元素,则必须按值而不是按引用返回:按引用返回将创建一个悬空指针。然而,按值返回是低效的:它涉及至少一个冗余复制构造函数调用。由于pop()不可能以高效和正确的方式返回值,因此更不明智地返回任何值并要求客户端使用top()来检查值堆栈的顶部。
std :: stack&lt; T>是一个模板。如果pop()返回顶部元素,则必须按值返回,而不是按照上述说明返回。这意味着,在调用者端,它必须被复制到另一种T类型的对象中。这涉及复制构造函数或复制赋值操作符调用。如果这种类型T足够复杂并且在复制构造或复制分配期间抛出异常怎么办?在这种情况下,rvalue,即堆栈顶部(由值返回)只是丢失,并且没有其他方法可以从堆栈中检索它,因为堆栈的弹出操作已成功完成!
实践方法是同时使用pop()
,top()
,empty()
:
T top()
{
return stack[size()-1];
}
void pop()
{
stack.erase(stack.begin()+stack.size()-1);
}
用法:
if (!stack.empty())
{
T t = top();
pop();
}
答案 2 :(得分:1)
有几种选择。一种是返回使用标准构造函数构造的T
实例:
return T();
另一种方法是返回一个特殊的sentinel包装器对象,它可以隐式转换为T
,并有一个比较运算符,以便用户可以检查它。
答案 3 :(得分:1)
你也可以做一些事情,比如将pop方法声明为void或更好,bool来获取操作的状态,并通过引用将T类型作为参数传递,以便将结果存储在其中:
bool Pop (T& item)
{
if (stack.size() != 0)
{
// your code
item = temp; // you can even use item instead of temp from the begining
return true;
}
return false;
}
答案 4 :(得分:1)
这是一种做法。我们的想法是将一个布尔标志与结果打包在一个元组中。该标志表示是否有结果。请注意,当前的实现要求T是默认的可构造的。
template<class T>
class Stack
{
private:
std::vector<T> stack;
public:
typedef std::tuple<bool, T> return_t;
void Push(const T& t)
{
stack.push_back(t);
}
return_t Pop()
{
if (stack.size()!=0)
{
T temp;
temp=stack[stack.size()-1];
stack.erase(stack.begin()+stack.size()-1);
return std::make_tuple(true, temp);
}
else
return std::make_tuple(false, T());
}
};
int main()
{
Stack<int> my_stack;
bool has_result;
int result;
my_stack.Push(5);
std::tie(has_result, result) = my_stack.Pop();
std::cout << "has result = " << has_result << "\n";
std::cout << "result = " << result << "\n";
std::tie(has_result, result) = my_stack.Pop();
std::cout << "has_result = " << has_result << "\n";
}