簡體   English   中英

函數中沒有return語句,返回非void

[英]no return statement in function returning non-void

我在編碼時是新手,對於此代碼,我收到“錯誤:函數返回非無效的返回語句:

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

關於我在做什么錯的任何想法? 謝謝!

函數簽名:

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

告訴編譯器您的函數將返回type T但是您的函數實際上不返回任何值,因此編譯器會警告您可能存在的愚蠢錯誤。

因此,根據您的情況,您需要確保這些語句,
myStack.pop_front(); myStack.front(); 實際上返回類型T

假設您正在使用一些標准的庫容器pop_front(); 只是刪除容器中的第一個元素,它不會返回任何內容。

您必須添加return關鍵字:

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

或類似的東西,具體取決於您對stack

短期解決方案是返回值,但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() )不應拋出任何東西,因為析構函數不得拋出 因此,明智的做法是假設該行未掛起並且將始終成功(除非您彈出一個空容器)。

由於正在復制數據,因此第一和第三行可能會拋出。

現在想象一下

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

完美運行:您已經准備好要返回一個值,並且您已經成功更改了保持對象的狀態。

但是之后

    return foo;  // May throw.

它拋出一個異常。 發生了什么:

  • 該函數未成功,調用者除異常外一無所有
  • 仍然,對象的狀態已被修改。
  • 而且,沒有人再擁有丟失對象的最新副本,該副本通常包含老板在致命事故之前幾秒鍾前致電的關鍵業務數據。

這與亞伯拉罕的保證相矛盾:

  • 無拋出保證:該操作將不會拋出異常。

  • 強有力的保證:操作已成功完成或引發了異常,從而使程序狀態與操作開始之前的狀態完全相同。

  • 基本保證:保留組件的不變式,並且不會泄漏任何資源。 之所以稱為弱保障,是因為在發生異常之后,系統處於安全但未知的狀態。

使用pop()返回一個值,您不能保證不會丟失任何信息。

另請參閱GotW#8GotW#82

您的簽名要求您返回T類型的對象。

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

要對此進行細分,可以使用template <class T>意味着對於您為T輸入的每個類,都將生成該代碼的另一個副本。 例如,如果您做了

堆棧intStack; 堆疊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;
}

當您簽名表明函數正在返回類型T時,您應該將代碼更改為以下兩個函數的代碼。

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

這將起作用:

 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
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM