2015-09-25 9 views
6

は、以下のコードを考えてみます。decltypeが末尾の戻り値型で使用されるのはなぜですか?

template< class T1 , class T2> 
auto calc(T1 a , T2 b) 
{ 
    return a + b ; 
} 


template< class T1 , class T2> 
auto calc(T1 a , T2 b) -> decltype(a + b) 
{ 
    return a + b ; 
} 

いただきました第二のコードの違い? これは違いがある場合やここで違いがある場合の例をいくつか挙げることができますか?

答えて

6

プレーンautoの戻り値の型はC++ 14の場合のみで、末尾の戻り値の型がdecltypeの場合はC++ 11の場合です。参照がピクチャに入力されるときに違いが生じる。このようなコードで:

#include <type_traits> 

struct Test 
{ 
    int& data; 

    auto calc1() 
    { 
     return data; 
    } 

    auto calc2() -> decltype(data) 
    { 
     return data; 
    } 
}; 

int main() 
{ 
    int x; 
    Test t{x}; 
    static_assert(std::is_same<int, decltype(t.calc1())>::value, ""); 
    static_assert(std::is_same<int&, decltype(t.calc2())>::value, ""); 
} 

あなたが->decltype()を削除して、同じ行動あなたのコードを維持したい場合は、あなたがリターンのreferencenessを維持するdecltype(auto)

decltype(auto) calc3() // same as calc2() above 
{ 
    return data; 
} 

C++ 14構文を使用することができますタイプも同様です。

すでにあなたの戻り値の型は参照であることがわかっている場合は、それを明示的

auto& calc4() // same as calc2() above 
{ 
    return data; 
} 
+0

レックスに答えてくれてありがとう:) [OK]を をので、離れて、両方が同じである保存の参照から。どちらを使うべきか、どちらを使うのが安全でしょうか? –

+0

それはあなたが望むものによって異なります。 'auto'と' auto& 'を使って、戻り型の参照が何であるかを明示します。時には 'decltype'がその利点を持つことがあります。インスタンシエーションなどを遅らせたいSFINAEのコンテキストで使用します。[しかし、それは高度なものです](http://stackoverflow.com/a/24109800/819272)。 – TemplateRex

+0

decltype(auto)はときどき危険です。次に例を示します。 decltype(auto)foo(){auto x = 5; return(x); } (x)は式なので、型はint&(多くの人がこのカッコで囲むサラウンド)です。この関数はローカルへの参照を返します。これはバグです! –

関連する問題