21

私が持っているとしましょう:

// This is all valid in C++11.
struct Foo {
    int i = 42;
    int& j = i;
};

// Let's take a pointer to the member "j".
auto b = &Foo::j; // Compiler is not happy here
// Note that if I tried to get a pointer to member "i", it would work, as expected.
Foo f;
std::cout << f.*b; // Try using the pointer to member

コンパイラは、参照であるためメンバーのアドレスを取得できないと不平を言います。正確には:

セマンティックの問題: 参照型 'int &' のメンバー 'j' へのポインターへのメンバーを形成できません

これを行うのは無意味に思えることはわかっていますが、なぜそれができないのか疑問に思っています。

なぜこれが不可能なのですか?

4

4 に答える 4

13

参照期間へのポインターを取得できないため、実行できません。

参照へのメンバー ポインターを取得できる場合、これはスタック上の参照の動作と矛盾します。C++ の態度は、参照が存在しないということです。そのため、それらへのポインタを形成することはできません。

たとえば、&f::aは とは異なる必要があり&f::bます。また、 を逆参照&f::bすることで、実質的に参照へのポインターを実現することになりますが、これは許可されていません。

于 2011-12-01T04:02:28.020 に答える
13

C++11 標準:

§8.3.3 p3 [dcl.mptr]
メンバーへのポインターは、クラス (9.4) の静的メンバー、参照型を持つメンバー、または「cv void」を指してはなりません。</p>

また、一般的に:

§8.3.1 p4 [dcl.ptr]
[ 注: 参照へのポインタはありません。8.3.2 を参照してください。[...] —エンドノート]

§8.3.2 p5 [dcl.ref]
参照への参照、参照の配列、および参照へのポインターは存在しないものとします。

于 2011-12-01T04:04:05.993 に答える
7

メンバー ポインター (メンバーへの単純なポインターとは対照的に) は、構造体への単なるオフセットであり、ポインターではありません。構造体自体 (または構造体へのポインター) と組み合わせてのみ、それを介してデータを取得できます。オフセットの値が構造体のアドレスに追加され、結果が逆参照されてメンバーの値が生成されます。

ここで、メンバーが参照であると仮定すると、それを介してデータにアクセスするには、既に逆参照が必要です (コンパイラーはそれを非表示にしますが、出力に対応する命令を吐き出す必要があります)。C++ が参照へのメンバー ポインターを許可する場合、それらはさらに別の型になります。つまり、ベースに追加してから 2 回逆参照する必要があるオフセットです。すでにあいまいな機能を改善するのは大変な作業です。それを禁止することは、はるかに良い方法です。

于 2011-12-01T04:18:16.880 に答える
1

参照へのポインターを作成できるようにしても、表現力は得られません。参照やポインターで簡単に実行できないような獣でできることは何もありません。そこから得られるのは、複雑さが増すことだけです。

また、参照であるメンバーへのポインターを作成することは、参照へのポインターを禁止する規則との一貫性のために許可されていません。これは、さらに複雑になるためです。言語の設計者は、おそらく、これらから得られるわずかな利益は価値がないと判断したのでしょう。

これは完全に私の意見です。

于 2011-12-01T05:05:13.863 に答える