2013-05-20 11 views
15

This earlier question尋ねるものthis[0]はC#で意味します。 C++では、this[0]は、 "thisで指される配列の0番目の要素"を意味します。これはC++でも安全ですか?

このように受信者オブジェクトを参照するためにC++で未定義の動作が発生しないことは保証されていますか?私はこの構文を使用することを主張しているわけではなく、この仕様が常に機能することを保証するかどうかはほとんど不思議です。

ありがとうございます!

+1

'&obj + 1'の行に沿って、明確に定義されていると確信しています。 – chris

+3

私は時々gdbで使ったことがあります: 'p complex-expression-that-yields-pointer'を実行したとしますが、ポインタではなくオブジェクトの内容を見たいので、 'と完了しました。式の先頭までスクロールしてかっこを追加する必要はありません(おそらく)。 – rodrigo

答えて

19

有効なオブジェクトポインタpの場合、p[0]*pに相当します。従ってthis[0]*thisに相当します。それ以上のことはありません。 [0]を使用して有効なポインタを逆参照できるように、thisを参照解除することができます。

つまり、*thisと書くのは「難しい」方法です。コードを難読化するために使用できます。スタンドアロンオブジェクトはサイズ1の配列として考えることができるので、おそらく特定の状況では便利です。(C++ 03より、加算演算子: "これらの演算子では、ポインタノンアレイオブジェクトへのポインタは、その要素タイプとしてオブジェクトの型を持つ長さ1の配列の最初の要素へのポインタと同じように動作します。 ")

PSコメントでJohannesが指摘したように、C++ 11の機能を使用することで、thisが不完全な型へのポインタであるコンテキストを思いつくことができます。この場合、this[0]式は無効になり、*this式は有効のままです。

+5

私はあなたがそれに気づいていると確信していますが、答えは異なっています。次のように書かれていますが、 'this [0]'を '* this'に置き換えると適切になります。 'struct A {auto f() - > decltype(this [0]); }; '。 –

+2

これは、 'p'が不完全な型へのポインタであるとき、' p [0] 'はヨハネスが言ったこととは何ですか?これを補うには、Johannesの例のように、まだ完成していないために型が不完全かもしれませんが、型が完了できないこともあります( 'T(*)[]'など)。もちろん、非オブジェクト型のポインタ型でも機能しません。 – hvd

11

this[0]*(this + 0)と同じです(実際はこれはちょっと奇妙ですが)。

+2

おとぎ話に申し訳ありませんが、ISO仕様でこれが保証されていますか?私はこのアイデンティティーを十分に認識していますが、仕様ではオブジェクトと配列が区別されることがよくあります。 – templatetypedef

+0

@templatetypedef、 '&obj + 1'は、' obj'が配列か単一オブジェクトかにかかわらず有効です。私はここでも同じことが当てはまります。 – chris

+3

@templatetypedef:実際には、 '[]'はポインタに対してのみ配列に対しては動作しません。配列はポインタに崩壊し、 '[]'はポインタとインデックスで動作します。それで、はい、それは保証されています。 – rodrigo

0

と同じです(定義によると)*(this + 0)と同等です。それは安全で明確に定義されていますが、変です。 thisは普通のポインタであるよう

3

うん、それは基本的にthis[0]*this

1

私の知る限りと同じことなのは、*thisと全く同じです。 はい、安全です。 (array有効時)

array[1]はFYI ...

-2

this[0]はそれが

struct A 
{ 
    void * _a; 
    int _b; 

    A * getThis(int index) 
    { 
     return &(this[index]); 
    } 
}; 

int main(int argc, char * argv[]) 
{ 
    A mas[100]; 

    std::cout << ((long long) mas[0].getThis(50) == (long long) &(mas[50])) << std::endl; 
    return 0; 
} 
をコメントに答えとして小規模なテストを追加しました非常に安全だ *(this + sizeof(this)*0)と同じである *(array + 1)と同じになります
+7

あなたの答えは技術的に正しいです。 'sizeof(this)'は不必要で、 'this [1]'が '*(this + sizeof(this)* 1)'と同じであることを意味します。あるいは、 'this [N]'は '*(this + sizeof(this)* N)'と一般的に同じです。もちろん、これは間違いです。 –

+0

@BenjaminLindley私の考えを証明する小さなテストを参照してください。 –

+3

あなたのテストでどの点を証明しようとしているのか分かりません。あなたは私のコメントを理解しましたか?私の指摘は、 'this [N]'は '*(this + sizeof(this)* N)'と同じではありませんが、私の意見では元の答えは同等であることを意味します。 'sizeof(this)'は完全に無意味であり、0で乗算されているので動作しません。しかし、0以外の値の他の 'N'では動作しません。だからあなたの公式にはなぜそれがありますか? –

関連する問題