1. ホーム
  2. c++

[解決済み] 新しい C++11 プログラムでは、末尾の戻り値の構文スタイルがデフォルトになるべきですか?[クローズド]

2023-01-20 06:22:55

質問

C++11 では、新しい関数構文がサポートされています。

auto func_name(int x, int y) -> int;

現在、この関数は次のように宣言されます。

int func_name(int x, int y);

新しいスタイルはまだ広く採用されていないようです (例えば gcc stl では)。

しかし、この新しいスタイルは、新しい C++11 プログラムのあらゆる場所で優先されるべきなのでしょうか、それとも必要な場合にのみ使用されるのでしょうか。

個人的には、可能であれば古いスタイルを好みますが、スタイルが混在するコードベースはかなり醜く見えます。

どのように解決するのですか?

末尾の戻り値の型を使用しなければならない場合があります。 最も顕著なのは、ラムダの戻り値型を指定する場合、末尾の戻り値型を介して指定する必要があることです。 また、戻り値の型が decltype を利用する場合、末尾のリターン型を使用しなければなりません (ただし、通常は declval<T> を使ってこの後者の問題を回避することができます)。

末尾の戻り値型には、他にもいくつかの小さな利点があります。 例えば、伝統的な関数構文を使用した非インラインのメンバー関数定義を考えてみましょう。

struct my_awesome_type
{
    typedef std::vector<int> integer_sequence;

    integer_sequence get_integers() const;
}; 

my_awesome_type::integer_sequence my_awesome_type::get_integers() const
{
    // ...
}

メンバ型定義は,クラス名が表示される前に ::get_integers の前に現れるまではスコープされないので、クラス名を2回繰り返さなければなりません。 もし、末尾にreturn型を使用すれば、型の名前を繰り返す必要はありません。

auto my_awesome_type::get_integers() const -> integer_sequence
{
    // ...
}

この例では、それほど大きな問題ではありませんが、長いクラス名やクラステンプレートのメンバー関数がインラインで定義されていない場合、可読性に大きな差が出ることがあります。

彼の "フレッシュ ペイント" C++Now 2012 のセッションで、Alisdair Meredith は、末尾の戻り値の型を一貫して使用すると、すべての関数の名前がきちんと並ぶと指摘しました。

auto foo() -> int;
auto bar() -> really_long_typedef_name;

のいたるところで、末尾のリターン型を使っています。 CxxReflect で、一貫してそれを使ったコードの例を探しているなら、そこを見てください (例えば type クラス ).