web-dev-qa-db-ja.com

これのアドレスを取得する際の「式はl値または関数指定子でなければなりません」エラー

私はこれをC++でやろうとしています:

class Abc
{
   int callFunction1()
};

void function1(Abc** c1) {//do something}

int Abc::callFunction1()
{
   function1(&this);
   return 0;
}

また、Visual Studio 2015で「式はL値または関数指定子である必要があります」というエラーが表示されます。そのため、どこが間違っているのかわかりません。私の知る限り、 &thisのタイプはAbc** 正しい?

関数の定義は私のものではありません。したがって、パラメーターの種類を変更することはできません。

5
disccip

エラーは十分に明確です。 thisは左辺値ではないため、そのアドレスを取得することはできません。オブジェクトのアドレスだけが必要な場合は、&thisではなくthisを渡し、関数宣言を次のように変更します。

void function1(Abc* c1) //To just pass a pointer

ただし、関数の定義は変更できないと述べたので、一時変数を作成してそのアドレスを渡すことができます。

auto temp = this;
function1(&temp);

仕組み:

  1. thisprvalue であり、そのアドレスを取得することができないため、それをポイントして左辺値に変換するために何かが必要です。ここではtemp
  2. tempthisを指すようになったため、間接的にではありますが、tempのアドレスを取得すると、実質的にthisのアドレスを取得します。
  3. したがって、左辺値のアドレスをfunction1に渡しているため、コードは期待どおりにコンパイルおよび動作します。
8
Arnav Borborah

thisは右辺値であり、式137または'a'と同じなので、そのアドレスを取得することはできません。

thisへのポインターへのポインターを取得する場合は、正しい型の新しい変数を作成する必要があります。

auto* ptr = this;
doSomething(&ptr);
4
templatetypedef

C++標準から(9.2.2.1 thisポインター)

1非静的(9.2.1)メンバー関数の本体では、キーワードthisはprvalue式ですであり、その値は関数が呼び出されるオブジェクトのアドレスです。

および(5.3.1単項演算子)

3単項&演算子の結果は、そのオペランドへのポインターです。 オペランドは左辺値にする必要がありますまたは修飾ID ...

より明確にするために、次のコードスニペットを検討してください。

たとえば、宣言がある場合

int x = 10;

その後、あなたは書くことはできません

int **p = &&x;

右の式では、&xprvalueであり、規格の2番目の引用によれば、単項演算子&prvalueに適用することはできません。

あなたは書くことができます

int *q = &x;
int **p = &q;

qlvalueであるためです。

4