ステートメントは何ですか
return {};
C ++ 11では、(たとえば)の代わりにそれをいつ使用するかを示します
return NULL;
または
return nullptr;
return;
価値がなく単純ですか?
return;
一方return{};
、戻り値の型がある場合は有効です。
ステートメントは何ですか
return {};
C ++ 11では、(たとえば)の代わりにそれをいつ使用するかを示します
return NULL;
または
return nullptr;
return;
価値がなく単純ですか?
return;
一方return{};
、戻り値の型がある場合は有効です。
回答:
return {};
「空のリスト初期化子で初期化された関数の戻り値型のオブジェクトを返す」ことを示します。正確な動作は、返されたオブジェクトのタイプによって異なります。
cppreference.comから(OPにはC ++ 11のタグが付けられているため、C ++ 14およびC ++ 17のルールを除外しました。詳細については、リンクを参照してください):
- braced-init-listが空で、Tがデフォルトのコンストラクターを持つクラス型である場合、値の初期化が実行されます。
- それ以外の場合、Tが集約型の場合、集約の初期化が実行されます。
- それ以外の場合、Tがstd :: initializer_listの特殊化である場合、Tオブジェクトは、コンテキストに応じて、braced-init-listから直接初期化またはコピー初期化されます。
そうでない場合は、Tのコンストラクターが2つのフェーズで考慮されます。
- std :: initializer_listを唯一の引数として、または残りの引数にデフォルト値がある場合は最初の引数として取るすべてのコンストラクターが検査され、オーバーロード解決によって型std :: initializer_listの単一の引数と照合されます
- 前のステージで一致が生成されない場合、Tのすべてのコンストラクターは、braced-init-listの要素で構成される引数のセットに対するオーバーロードの解決に参加します。ただし、狭くない変換のみが許可されます。この段階で、コピーリストの初期化に最適な一致として明示的なコンストラクターが生成される場合、コンパイルは失敗します(単純なコピーの初期化では、明示的なコンストラクターはまったく考慮されません)。
それ以外の場合(Tがクラス型ではない場合)、braced-init-listに要素が1つしかなく、Tが参照型ではないか、または要素の型と互換性のある参照型である場合、Tは直接初期化(直接リスト初期化)またはコピー初期化(コピーリスト初期化)、ただし、ナロー変換は許可されません。
- それ以外の場合、Tが要素の型と互換性のない参照型である場合。(参照が非const左辺値参照の場合、これは失敗します)
- それ以外の場合、braced-init-listに要素がない場合、Tは値で初期化されます。
C ++ 11以前はstd::string
、を返す関数の場合、次のように記述していました。
std::string get_string() {
return std::string();
}
C ++ 11で中かっこ構文を使用すると、型を繰り返す必要はありません。
std::string get_string() {
return {}; // an empty string is returned
}
return NULL
そしてreturn nullptr
関数はポインタ型を返すときに使用されるべきです。
any_type* get_pointer() {
return nullptr;
}
ただし、NULL
C ++ 11以降は非推奨です。これは整数値(0)の単なるエイリアスでnullptr
あり、実際のポインタ型だからです。
int get_int() {
return NULL; // will compile, NULL is an integer
}
int get_int() {
return nullptr; // error: nullptr is not an integer
}
これはおそらく混乱しています:
int foo()
{
return {}; // honestly, just return 0 - it's clearer
}
これはおそらくありません:
SomeObjectWithADefaultConstructor foo()
{
return {};
// equivalent to return SomeObjectWithADefaultConstructor {};
}
initializer_list
コンストラクターがある場合、デフォルトのコンストラクターが使用できない場合はそれが使用されませんか?
return {}
次と同等ではないreturn SomeObjectWithADefaultConstructor{};
return {};
これ{}
は、戻り値の初期化子であることを意味します。戻り値は空のリストでリスト初期化されます。
C ++標準の[stmt.return]に基づく戻り値の背景を次に示します。
値で戻る関数(つまり、戻り値の型が参照ではなくvoid
)の場合、戻り値と呼ばれる一時オブジェクトがあります。このオブジェクトはreturn
ステートメントによって作成され、その初期化子はreturnステートメントの内容によって異なります。
戻り値は、関数を呼び出したコードの完全式が終了するまで存続します。クラス型の場合は、呼び出し側が直接参照をバインドすることによって寿命が延長されない限り、デストラクタが実行されます。
戻り値は、2つの異なる方法で初期化できます。
return some_expression;
-戻り値はからコピー初期化されますsome_expression
return { possibly_empty_list };
-戻り値は
リストからリスト初期化されます。T
関数の戻り値の型であると仮定すると、次の点とreturn T{};
は異なることに注意してください。return {}
前者では、一時変数T{}
が作成され、戻り値はその一時変数からコピー初期化されます。
T
アクセス可能なコピー/移動return {};
コンストラクタがない場合、これはコンパイルに失敗しますが、これらのコンストラクタが存在しない場合でも成功します。したがって、return T{};
これはコピー省略コンテキストであるため、コピーコンストラクタなどの副作用を示す可能性があります。
以下は、C ++ 14(N4140 [dcl.init.list] / 3)でのリスト初期化の簡単な要約です。ここで、初期化子は空のリストです。
T
集合体で、各部材は、その初期化されブレース-OR-等しい初期それが1つを持っていたならば、そうでない場合によってかのように{}
(そう再帰的手順を適用します)。T
、ユーザーが提供するデフォルトコンストラクタを持つクラス型で、そのコンストラクタが呼び出されます。T
が暗黙的に定義されたクラス型、または= default
デフォルトのコンストラクタを持つクラス型の場合、オブジェクトはゼロで初期化され、デフォルトのコンストラクタが呼び出されます。T
でstd::initializer_list
、戻り値は空のようなリストがあります。T
、クラス型ではない-戻り値の型を配列にすることはできません)、戻り値はゼロで初期化されます。{}
、すべてのメンバーをで再帰的に初期化します。これはvalue-initである場合とそうでない場合があります。
これは、メソッドの戻り値の型の新しいインスタンスの一種の略です。