なぜint x {y = 5}が可能なのですか?


10
int main() {
    int y;
    int x{ y = 5 };
    //x is 5
}

y = 5は計算可能な式ではないので、これはどのように可能ですか?

また、コンパイラまたはIDEがmain()がintを返さないことについて不平を言わないのはなぜですか?


8
y = 5 式であり、valueを持っています5。なぜそうではないと思いますか?
役に立たない

2
の不足returnについてはmainこの質問を参照してください。
ウォールナット、

3
さらに良いことに、2番目の質問を削除します。一つ一つの質問につき質問はスタックオーバーフローに有利なモデルです。
StoryTeller-Unslander Monica

おそらく、y = 5ここでなぜ5 になるのかという質問を再定義する必要があります。代入演算子が何かを返す可能性は、確かにC / C ++の奇妙な機能です。
user7860670

回答:


11

最後の質問から始めます

また、コンパイラまたはIDEがmain()がintを返さないことについて不平を言わないのはなぜですか?

C ++標準に準拠(6.6.1メイン関数)

5 mainのreturnステートメントには、main関数を終了し(自動ストレージ期間を持つオブジェクトを破棄)、戻り値を引数としてstd :: exitを呼び出す効果があります。制御がmainの複合ステートメントの終わりから流れ出る場合、その効果はオペランド0の戻りと同じです(18.3も参照)。

そしてこの質問に関連して

y = 5は計算可能な式ではないので、これはどのように可能ですか?

C ++標準から(8.18代入演算子と複合代入演算子)

1代入演算子(=)と複合代入演算子はすべて右から左にグループ化されます。すべての左オペランドとして変更可能な左辺値が必要であり、左オペランドを参照する左辺値を返します。

この宣言をSp

int x{ y = 5 };

同等に2つのステートメントに分割できます

y = 5;
int x{ y };

さらに、C ++では、変数yへの参照を次のようにすることもできます。

int &x{ y = 5 };

ここにデモプログラムがあります

#include <iostream>

int main() 
{
    int y;
    int &x{ y = 5 };    

    std::cout << "y = " << y << '\n';

    x = 10;

    std::cout << "y = " << y << '\n';
}

その出力は

y = 5
y = 10

あなたはこの宣言をするかもしれません

int x{ y = 5 };

同様に書き直し

int x = { y = 5 };

ただし、これらの(上記の宣言と同様に見える)2つの宣言には違いがあることを考慮してください。

auto x{ y = 5 };

そして

auto x = { y = 5 };

最初の宣言では、変数xのタイプはintです。2番目の宣言では、変数xのタイプはstd::initializer_list<int>です。

違いをわかりやすくするには、オブジェクトの値がどのように出力されるかを確認してください。

#include <iostream>

int main() 
{
    int y;
    auto x1 { y = 5 };  

    std::cout << "x1 = " << x1 << '\n';

    auto x2 = { y = 10 };   

    std::cout << "*x2.begin()= " << *x2.begin() << '\n';

    std::cout << "y = " << y << '\n';

    return 0;
}

プログラム出力は

x1 = 5
*x2.begin()= 10
y = 10

16

y = 5は計算可能な式ではないので、これはどのように可能ですか?

これは代入であり、代入により値、つまり「左オペランドのcv非修飾型」が生成されます。[expr.ass / 3]を参照してください。したがって、y = 5結果はy、つまり、5初期化に使用されますx

2番目の質問については、メイン(または[basic.start.main / 5])のcppreferenceを参照してください。

main関数の本文にはreturnステートメントを含める必要はありません。制御がreturnステートメントに出会わずにmainの終わりに達した場合、結果はを実行したことになりreturn 0;ます。

したがって、コンパイラまたはIDE returnが最後にステートメントがないことを警告するのは、main明らかに間違っています。確かに、常にreturnvoid関数のexecptmainからオブジェクトを拒否する必要があるという事実は一種の...まあ、歴史的な理由から私は推測しています。


2
式は結果として値を返すことができますが、値を返すことができるのは関数のみreturnです。-pedantic
役に立たない

このint x {y = 5}だと思います。ステートメントはc
bhuraで

@bhura-問題はC ++ではなくC ++に関するものです
StoryTeller-Unslander Monica

おそらく、必須ではない場合でも、mainから値を返すことは通常、良い習慣と見なされます。
アコンカグア

4

operator=()変数に割り当てられる値である値をもたらします。このため、次のように割り当てをチェーンすることができます。

int x, y, z;
x = y = z = 1;

代入式は持っていた値を。関数には戻り値があります。式にはありません。
ピートベッカー

3

cppreferenceのドキュメントを見るとoperator=()割り当てられたオブジェクトへの参照を返すことがわかります。したがって、割り当ては、割り当てられたオブジェクトを返す式として使用できます。

次に、中かっこを使用した通常の割り当てです。

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