如何在返回类型为.的函数中返回None

How can I return None in a function that has return type?

本文关键字:函数 返回 None 返回类型      更新时间:2023-10-16

我的代码如下:

#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    
    }

In pop function: I want if stack.size==0;弹出函数返回空

我怎么能做到呢?

这基本上是一个如何处理非全函数的问题,即不一定为所有可能的输入定义的函数。有很多方法可以做到这一点,但没有一种是类型安全的:

  1. 有两个单独的函数用于检索和删除堆栈的顶部元素,类似于std::stack::top()std::stack::pop()

  2. 使用引用参数并返回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);
    }
    
  3. 返回boost::optional<T>

  4. 返回默认构造的T实例。这要求T是默认可构造的,这已经被一些std::vector成员函数所强制。

  5. 抛出异常,说明违反了一个先决条件。

  6. 不定义弹出空堆栈的行为

我推荐#1、#2或#3,这取决于你的偏好,以及什么最适合周围的代码。

您可能仍然希望采用与std::stack相同的方法,将std::stack::topstd::stack::pop分开。您不希望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()来检查和删除top元素,而不是将两者组合在一个成员函数中?事实上,这样设计是有原因的。如果pop()返回顶部元素,它必须按值返回而不是按引用返回:按引用返回将创建一个悬空指针。然而,按值返回是低效的:它至少涉及一个冗余的复制构造函数调用。由于pop()不可能以既有效又正确的方式返回值,因此更明智的做法是根本不返回值,并要求客户端使用top()来检查堆栈顶部的值。

std::堆栈& lt;T>为模板。如果pop()返回顶部元素,它必须按值返回,而不是按照上面的解释按引用返回。这意味着,在调用方端,它必须复制到另一个T类型的对象中。这涉及到复制构造函数或复制赋值操作符调用。如果这个类型T足够复杂,并且在拷贝构造或拷贝赋值期间抛出异常怎么办?在这种情况下,右值,即堆栈顶部(按值返回)只是丢失了,并且没有其他方法可以从堆栈中检索它,因为堆栈的弹出操作已经成功完成!

实践方法是同时使用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();
}

有几个选择。一种是返回用标准构造函数构造的T实例:

return T();

另一种方法是返回一个特殊的哨兵包装器对象,该对象可以隐式地转换为T,并具有比较操作符,以便用户可以检查它。

这里有一种方法。其思想是将布尔标志与结果打包在一个元组中。标志表示是否有结果。请注意,当前的实现要求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";
}

您还可以这样做,例如将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;
}