This earlier question問什麼this[0]
在C#中的含義。在C++中,this[0]
表示「this
指向的數組的第零個元素」。這是[0]在C++中安全嗎?
是否保證不會導致C++中的未定義行爲以這種方式引用接收者對象?我並不是主張使用這種語法,並且大部分人都很好奇這個規範是否能夠保證這一點始終有效。
謝謝!
This earlier question問什麼this[0]
在C#中的含義。在C++中,this[0]
表示「this
指向的數組的第零個元素」。這是[0]在C++中安全嗎?
是否保證不會導致C++中的未定義行爲以這種方式引用接收者對象?我並不是主張使用這種語法,並且大部分人都很好奇這個規範是否能夠保證這一點始終有效。
謝謝!
對於任何有效的對象指針p
,p[0]
相當於*p
。所以this[0]
相當於*this
。沒有什麼更多。就像您可以使用[0]
取消引用任何有效指針一樣,您可以使用它取消引用this
。
換句話說,這只是一個「棘手」的方式來編寫*this
。它可以用來混淆代碼。它可能也可以在某些特定情況下用於有用的目的,因爲任何獨立對象都可以被認爲是大小爲1的數組。(從C++ 03開始,添加操作符:「爲了這些運算符的目的,指針到非數組對象的行爲與指向長度爲1的數組的第一個元素的指針相同,對象的類型作爲其元素類型。「)
PS正如Johannes在評論中指出的那樣,通過使用C++ 11功能,可以想出一個上下文,其中this
是指向不完整類型的指針。在這種情況下,this[0]
表達式變爲無效,而*this
表達式仍然有效。
我很確定你知道它,但答案表明它有所不同。以下是不合格的,用'* this'替換'this [0]'使得它格式良好。 'struct A {auto f() - > decltype(this [0]); };'。 –
對,約翰內斯說,'p [0]'不起作用,當'p'是一個指向不完整類型的指針時。爲了補充說明,類型可能是不完整的,因爲它尚未完成,如約翰內斯的例子,但也可能是因爲類型不能完成(例如'T(*)[]')。它(當然)也不適用於非對象指針類型。 – hvd
this[0]
與*(this + 0)
相同,所以確實沒問題(雖然有點奇怪)。
對於迂腐,但ISO規範保證呢?我很清楚這個身份,但是這個規範經常會區分對象和數組。 – templatetypedef
@templatetypedef,儘管'obj'是一個數組還是一個對象,'&obj + 1'仍然有效。我會假設這裏同樣適用。 – chris
@templatetypedef:實際上,'[]'不能在數組上操作,只能在指針上操作。數組衰減爲一個指針,'[]'與指針和索引一起工作。所以,是的,這是有保證的。 – rodrigo
它等效於(根據定義)*(this + 0)
,與*this
相同。它是安全和明確的,但很奇怪。
是的,這是同樣的事情*this
據我所知基本上this[0]
是完全一樣*this
,因爲this
只是一個普通的指針。 所以是的,它是安全的使用。
array[1]
是一樣的*(array + 1)
(當array
有效)FYI ...
this[0]
是一樣的*(this + sizeof(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;
}
雖然你的答案*技術*正確。 'sizeof(this)'是多餘的,意味着'this [1]'與'*(this + sizeof(this)* 1)'相同。或者說這個[N]'通常等同於*(this + sizeof(this)* N)'。這當然是錯誤的。 –
@BenjaminLindley看到一個小測試,我認爲,證明了我的觀點 –
我不知道你想用你的測試證明什麼觀點。你瞭解我的意見嗎?我的觀點是'this [N]'* *不等於'*(this + sizeof(this)* N)',但在我看來,您的原始答案意味着它們是等價的。 'sizeof(this)'是完全沒有意義的,只會發生,因爲它被乘以0.但除了0之外,對於任何其他的N值,它都不起作用。那麼爲什麼你的公式? –
我非常肯定它的定義很明確,沿着'&obj + 1'的方向走。 – chris
我有時用gdb使用它:假設你做了'p complex-expression-that-yield-pointer',但你想看到對象的內容,而不是指針,所以按下鍵入'[0] '完成了。無需滾動到表達式的開頭並添加括號(可能)。 – rodrigo