関数の見出しにある矢印演算子(->)


128

私は次のコードに出くわしました:

template <typename T, typename T1> auto compose(T a, T1 b) -> decltype(a + b) {
   return a+b;
}

理解できないことが1つあります。

->関数の見出しで矢印演算子()が何を意味するかはどこで確認できますか?純粋に論理的には、->演算子が型を決定し、それautoが推定されると思いますが、これをまっすぐに取得したいと思います。情報が見つかりません。


2
これは、末尾の戻り型構文の一部です。stackoverflow.com/a/4113390/962089を
chris

2
これは演算子ではなく、構文の一部です。
texasbruce 2014年

1
「どこで読めますか?」に対する回答として、C ++仕様が最も信頼できます。資金がないか、$$を使いたいという欲求がなければ、最後のワーキングドラフトは十分に近く、無料であることがよくあります。これらの仕様は高度にテクノスピークであるため、ISO仕様の読み方に精通していないため、cplusplus.comやcppreference.comなどの信頼できないサイトを試してください。ただし、通常は非常に正確です。注:末尾の戻り値の型は、C ++ 14以降では省略できる場合があります。
Les

回答:


205

C ++ 11では、関数宣言には2つの構文があります。

    戻り型 識別子 ( 引数宣言... )

そして

    auto 識別子の ( 引数宣言... ) -> return_type

それらは同等です。これらが同等であるのに、なぜ後者を使用したいのですか?さて、C ++ 11 decltypeは、式のタイプを記述できるこの素晴らしいものを導入しました。したがって、引数の型から戻り値の型を導出したい場合があります。だからあなたは試してみます:

template <typename T1, typename T2>
decltype(a + b) compose(T1 a, T2 b);

コンパイラーは、それが何であるかaを知らずbdecltype引数に含まれていることを通知します。これは、引数リストによってのみ宣言されているためです。

declvalと宣言済みのテンプレートパラメータを使用すると、問題を簡単に回避できます。お気に入り:

template <typename T1, typename T2>
decltype(std::declval<T1>() + std::declval<T2>())
compose(T1 a, T2 b);

今は本当に冗長になっていますが。したがって、代替宣言構文が提案および実装され、今、あなたは書くことができます

template <typename T1, typename T2>
auto compose(T1 a, T2 b) -> decltype(a + b);

冗長性が低く、スコープルールを変更する必要がありませんでした。


C ++ 14の更新: C ++ 14では、

    auto 識別子の ( 引数宣言... )

関数が使用前に完全に定義されており、すべてのreturnステートメントが同じ型に推定される限り。->あなたがソースファイルで体を非表示にする場合の構文は、(ヘッダで宣言さ)公共の機能のために有用まま。テンプレートではそれができないことはやや明らかですが、他の方法では書くのが難しいいくつかの具象型(通常はテンプレートメタプログラミングによって派生)があります。


2
とても良い、きちんとした有益な返信@Jan Hudec。突き上げます。そのような関数で型C++14を使用するときに、パーツを必要とせずに何か変更されたものはありますか?今では冗長ですか、それともまだ使用する必要がある他のケースがありますか?それともコンパイラ固有の拡張ですか?autoreturn-> decltype(a + b)
Shadi 2017

1
@ Shadi、C ++ 14にはN3638が含まれています。これにより、関数が使用前に完全に定義され、すべてのステートメントが同じ型に演繹される限りauto->表記としてなしで宣言された戻り型を演繹できますreturn->ソースファイルの本文を非表示にしながらパブリック関数の演繹を使用する場合は、この表記は依然として役立ちます。
Jan Hudec 2017

23

わかりやすい英語では、戻り値の型は、との合計の推定型であることを示しaていbます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.