2012-02-29 5 views
0
を返す関数でノーreturn文

イム新しいと私は、「エラー:非voidを返す関数でのノーreturn文」を取得、このコードのために:コーディングでは非空

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

私がやっているものの任意のアイデアを違う?ありがとう!

答えて

3

関数のシグネチャ:

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

は、あなたの関数が実際にどのような値を返さないので、コンパイラはあなたにあなたの部分の可能愚かな間違いのワーリングを与えるが、あなたの関数がtype Tを返すことをコンパイラに指示します。

だからあなたはあなたのケースであなたは文、
myStack.pop_front(); & myStack.front();が実際にタイプTを返すことを確認する必要があります。あなたには、いくつかの標準ライブラリのコンテナを使用していると仮定すると、

pop_front();はちょうどそれが何も返さないコンテナ内の最初の要素を削除します。

+1

「それは何も返さない」 - その理由は、値で 'T'を返すことは 'T'をコピー伴う可能性があるということで、例外をスローする可能性がありますいくつかのタイプ 'T'のためにこれは、スタックの前面が削除されていることを意味しますが、関数を返すのではなく投げたため、値を見る方法がありません。したがって、あなたの 'Stack'クラスはおそらく同様に' pop'をvoidに戻すべきです。何らかの理由で値を返さなければならない場合は、 '{T t = peek();}を実行します。 myStack.pop_front(); tを返す。 }}、関数が基本的な例外保証のみを提供していることを文書化する。 –

0

あなたの署名は少しtemplate <class T>これを打破するには、型T

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

のオブジェクトを返すことが求められますが、あなたがTのためのコードの別のコピーを入れ、クラスごとに生成されることを意味します。例えば、そうした場合

スタックintStack; スタックdoubleStack;

コンパイラは、あなたの2つのコピーを生成しますStackクラス:1つはintに特化し、もう1つは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; 
} 
+0

'pop()'が返り値型のvoidの場合は非常に優れています。 –

+0

@phresnel - ああ、元の質問と一致しません;) –

1

を説明するためにあなたがリターンキーワードを追加する必要があります。あなたのimlementationに応じて、

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

または類似した何かをstack

0

シグネチャは、関数がT型を返すことを示しているので、両方の関数でコードを次のように変更する必要があります。

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

pop_front()はT型のものを返しません。通常はvoidを返します –

+0

ahhはどのAPIミスマックが提供しているか分かりません。何かを返す必要があります。 – Kunal

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

をshortviewedソリューションはpop()がタイプvoidのであれば、それは優れている、値を返すことですが。

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ので、何かを投げてはいけません:

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

の理由は、あなたが何かを返す例外安全pop() -functionを書くことができないということです。したがって、行が空ではなく、常に成功すると仮定することは賢明です(空のコンテナをポップするときを除いて)。

データがコピーされているため、1行目と3行目がスローされることがあります。あなたが返される準備ができて値を持っている、とあなたが保持対象物の状態を正常に変更されている:

今完璧にその

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

実行を想像してみてください。

しかし、その後

return foo; // May throw. 

強打それが例外をスローします。何が起こった:

  • 機能が成功しなかった、呼び出し側はまだ、まだ、オブジェクトの状態が変更されている例外
  • 以外は何も得ませんでした。
  • そして、誰もが持っている一般的に上司が秒間にわたり電話をかけていること、重要なビジネスデータが含まれているもはや失われたオブジェクトの最新のコピーまでの前Abrahams Guaranteesにこれは矛盾している致命的な事故

を持つ前:

  • The no-throw guarantee: that the operation will not throw an exception.

  • The strong guarantee: that the operation has either completed successfully or thrown an exception, leaving the program state exactly as it was before the operation started.

  • The basic guarantee: that the invariants of the component are preserved, and no resources are leaked. Often referred to as the weak guarantee, because following an exception the system is left in a safe, but unknown, state.

値を返すpop()を指定すると、情報が失われないことを保証することはできません。

も参照してくださいGotW #8GotW #82

関連する問題