函数返回非void时没有return语句

时间:2012-02-29 08:24:10

标签: c++ function return-value

我是编码的新手,我得到“错误:函数返回non-void中没有return语句”代码:

template <class T>
T Stack<T>::pop()
{
  `myStack.pop_front();
}
template <class T>
T Stack<T>::peek() const
{
  myStack.front();
}

我做错了什么想法?谢谢!

6 个答案:

答案 0 :(得分:3)

功能签名:

template <class T> T Stack<T>::pop()

告诉编译器你的函数将返回一个type T,但是你的函数实际上并没有返回任何值,因此编译器会让你知道你可能犯的愚蠢错误。

因此,在您的情况下,您需要确保声明,
myStack.pop_front();&amp; myStack.front();实际上返回了T类型。

假设您正在使用某个标准库容器,pop_front();只删除容器中的第一个元素,它不会返回任何内容。

答案 1 :(得分:1)

您必须添加返回关键字:

template <class T>
T Stack<T>::pop()
{
  return myStack.pop_front();
}
template <class T>
T Stack<T>::peek() const
{
  return myStack.front();
}

或类似内容,具体取决于您对stack的承诺。

答案 2 :(得分:0)

您的签名要求您返回T类型的对象。

template <class T> T Stack<T>::pop()

要将此分解为template <class T>,意味着对于您为T放入的每个类,将生成另一个代码副本。例如,如果你做了

Stack intStack; Stack doubleStack;

编译器会生成两个Stack类的副本:一个专用于int,另一个专用于double。

所以当你写

template <class T>
T Stack<T>::pop()
{
  myStack.pop_front();
}

您需要返回专门类型的对象。 pop_front()仅删除第一个元素。你需要访问它删除第一个项目然后返回它。

这可能不是最好的方式,而是说明我的观点

template <class T>
T Stack<T>::pop()
{
  T tmp = myStack.front();
  myStack.pop_front();
  return tmp;
}

答案 3 :(得分:0)

当您签名表明函数返回类型T时,您应该将代码更改为以下两个函数的代码。

template <class T>
T Stack<T>::peek()
{
  return myStack.front();
}

答案 4 :(得分:0)

这将有效:

 template <class T>
    void Stack<T>::pop()
    {
      `myStack.pop_front();
    }
    template <class T>
    void Stack<T>::peek() const
    {
      myStack.front();
    }

或者:

template <class T>
T Stack<T>::pop()
{
  `myStack.pop_front();
  // return something of type T
}
template <class T>
T Stack<T>::peek() const
{
  myStack.front();
  //return something of type T
}

答案 5 :(得分:0)

虽然短视图解决方案是返回一个值,但如果pop()的类型为void则更好。

template <typename T>
void Stack<T>::pop() {
    ...
}

原因是您无法编写异常安全pop() - 返回内容的函数:

template <typename T>
T Stack<T>::pop() {
    T foo = stor_.top(); // May throw.
    stor_.pop(); // This line shall never throw.
    return foo;  // May throw.
}

第二行(pop())不应该扔东西,因为destructors shall not throw。因此,假设该行不是并且将始终成功(除非您弹出空容器时)是理智的。

第一行和第三行可能因为正在复制数据而抛出。

现在想象一下

    T foo = stor_.top(); // May throw.
    stor_.pop(); // This line shall never throw.

运行完美:您已准备好返回一个值,并且您已成功更改了保持对象的状态。

但是

    return foo;  // May throw.

爆炸它会引发异常。发生了什么:

  • 该功能没有成功,除了异常外,来电者什么都没有。
  • 目前,对象的状态已被修改。
  • 并且没有人拥有丢失对象的最新副本,其中通常包含老板在发生致命事故之前几秒钟打电话的关键业务数据

这与Abrahams Guarantees

相矛盾
  
      
  • 无投掷保证:操作不会抛出异常。

  •   
  • 强有力的保证:操作已成功完成或抛出异常,使程序状态与操作开始前完全一致。

  •   
  • 基本保证:保留组件的不变量,不泄漏任何资源。通常被称为弱保证,因为在异常之后系统处于安全但未知的状态。

  •   

如果pop()返回一个值,则无法保证不会丢失任何信息。

另请参阅GotW #8GotW #82