1. ホーム
  2. c++

[解決済み] なぜC++では参照は "const "ではないのですか?

2023-05-03 17:56:42

疑問点

const変数とは、一度代入された変数は変更できないことを表しています。

int const i = 1;
i = 2;

上のプログラムはコンパイルに失敗し、gccはエラーでプロンプトを表示します。

assignment of read-only variable 'i'

問題ありません、私は理解できますが、次の例は私の理解を超えています。

#include<iostream>
using namespace std;
int main()
{
    boolalpha(cout);
    int const i = 1;
    cout << is_const<decltype(i)>::value << endl;
    int const &ri = i;
    cout << is_const<decltype(ri)>::value << endl;
    return 0;
}

出力されるのは

true
false

奇妙ですね。一旦参照が名前/変数に束縛されると、この束縛を変更することはできず、その束縛されたオブジェクトを変更することが分かっています。だから、私は、型が ri と同じであるべきです。 i と同じであるべきです。 iint const であるのか、なぜ ri ではなく const ?

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

これは直感に反するように思えるかもしれませんが、これを理解する方法は、ある点では、こう気づくことだと思います。 リファレンス 構文的に のように ポインタ .

これは、論理的に考えて ポインタ :

int main()
{
    boolalpha(cout);

    int const i = 1;
    cout << is_const<decltype(i)>::value << endl;

    int const* ri = &i;
    cout << is_const<decltype(ri)>::value << endl;
}

出力します。

true
false

でないことが分かっているので、これは論理的です。 ポインタオブジェクト であること(他の場所を指すようにすることができます)、それは指されているオブジェクトであることを知っているからです。

ということで、私たちは正しく constness ポインタ として返されます。 false .

にしたい場合は ポインタ そのものを const と言わなければならない。

int main()
{
    boolalpha(cout);

    int const i = 1;
    cout << is_const<decltype(i)>::value << endl;

    int const* const ri = &i;
    cout << is_const<decltype(ri)>::value << endl;
}

出力します。

true
true

で、構文的な類似性が見られると思います。 参照 .

しかし 参考文献 はポインタとは意味的に異なり、特に 1 という重要な点において 再結合 を行うことはできません。

そのため、たとえ を参照する と同じ構文で ポインタ と同じですが、ルールが異なるため、この言語では 参照 そのものを const のようにします。

int main()
{
    boolalpha(cout);

    int const i = 1;
    cout << is_const<decltype(i)>::value << endl;

    int const& const ri = i; // COMPILE TIME ERROR!
    cout << is_const<decltype(ri)>::value << endl;
}

言語規則で 参照 と同じようにリバウンドしないようにするためです。 ポインタ は、(それが宣言されていない場合 const ).

というわけで、質問に答えます。

Q) C++で "reference "が "const "でないのはなぜですか?

あなたの例では、構文によって参照されるものが const を宣言しているのと同じです。 ポインタ .

善し悪しは別にして、私たちは 参照 そのもの const といった具合ですが、もしそうだとすると、このようになります。

int const& const ri = i; // not allowed

Q) 一旦参照を名前/変数にバインドすると、このバインドを変更することはできず、バインドされたオブジェクトを変更することになります。 ですから、私は ri と同じであるべきだと思います。 i の場合 iint const は、なぜ riconst ?

なぜ decltype() がオブジェクトに転送されないのはなぜですか? レフェレンス はバインドされていますか?

との意味上の等価性のためでしょう。 ポインタ と同じであり、また、おそらく decltype() (宣言型)であったものを振り返ることである。 宣言された を振り返ることです。