GİRİŞ
ISOC ++ 11 (resmi olarak ISO / IEC 14882: 2011), C ++ programlama dili standardının en son sürümüdür. Bazı yeni özellikler ve kavramlar içerir, örneğin:
- rvalue referansları
- xvalue, glvalue, prevalue ifade değeri kategorileri
- anlambilimi taşıma
Yeni ifade değeri kategorilerinin kavramlarını anlamak istiyorsak, değer ve değer referansları olduğunu bilmemiz gerekir. Değerlerin sabit olmayan değer referanslarına geçirilebileceğini bilmek daha iyidir.
int& r_i=7; // compile error
int&& rr_i=7; // OK
Çalışma taslağı N3337'den (yayınlanan ISOC ++ 11 standardına en yakın taslak) Lvalues ve rvalues başlıklı alt bölümden alıntı yaparsak değer kategorileri kavramlarının sezgisini kazanabiliriz.
3.10 Değerler ve değerler [basic.lval]
1 İfadeler, Şekil 1'deki sınıflandırmaya göre sınıflandırılmıştır.
- Bir lvalue (tarihsel olarak denir, çünkü atama ifadesinin sol tarafında lvalues görünebilir) bir işlevi veya nesneyi belirtir. [Örnek: E, işaretçi türünün bir ifadesiyse, * E, E'nin işaret ettiği nesneye veya işleve başvuran bir lvalue ifadesidir. Başka bir örnek olarak, dönüş türü bir değer referansı olan bir işlev çağrılmasının sonucu bir değerdir. —End örneği]
- Bir xvalue (bir "eXpiring" değeri), genellikle kullanım ömrünün sonuna yakın olan bir nesneyi de belirtir (örneğin, kaynaklarının taşınabilmesi için). Xvalue, rvalue referanslarını içeren belirli ifade türlerinin sonucudur (8.3.2). [Örnek: Dönüş türü rvalue başvurusu olan bir işlevi çağırmanın sonucu xvalue'dur. —End örneği]
- Bir glvalue (“genelleştirilmiş” lvalue) bir lvalue veya xvalue'dur.
- Bir değer (tarihsel olarak, atama ifadesinin sağ tarafında görünebileceğinden, değer olarak adlandırılır) bir x değeri,
geçici bir nesne (12.2) veya alt nesnesi veya
bir nesne ile ilişkili olmayan bir değerdir .
- Bir değer (“saf” değer) x değeri olmayan bir değerdir. [Örnek: Dönüş türü
başvuru olmayan bir işlevi çağırmanın sonucu bir ön değerdir. 12, 7.3e5 veya
true gibi bir değişmez değerin değeri de bir değerdir. —End örneği]
Her ifade, bu sınıflandırmadaki temel sınıflandırmalardan birine aittir: lvalue, xvalue veya prevalue. Bir ifadenin bu özelliğine değer kategorisi denir.
Ancak, bu alt bölümün kavramları net bir şekilde anlaması için yeterli olduğundan emin değilim, çünkü "genellikle" gerçekten genel değil, "ömrünün sonuna yakın" gerçekten somut değil, "değer referanslarını içeren" gerçekten net değil, ve "Örnek: Dönüş türü rvalue başvurusu olan bir işlevi çağırmanın sonucu xvalue'dur." Bir yılan kuyruğunu ısırmış gibi geliyor.
BİRİNCİ DEĞER KATEGORİLERİ
Her ifade tam olarak bir birincil değer kategorisine aittir. Bu değer kategorileri, değerlik, değer ve ön değer kategorileridir.
Sol taraf
E ifadesi, yalnızca E, ALREADY'nin E dışında erişilebilmesini sağlayan bir kimliğe (adres, ad veya diğer ad) sahip olduğu bir varlığı ifade ediyorsa lvalue kategorisine aittir.
#include <iostream>
int i=7;
const int& f(){
return i;
}
int main()
{
std::cout<<&"www"<<std::endl; // The expression "www" in this row is an lvalue expression, because string literals are arrays and every array has an address.
i; // The expression i in this row is an lvalue expression, because it refers to the same entity ...
i; // ... as the entity the expression i in this row refers to.
int* p_i=new int(7);
*p_i; // The expression *p_i in this row is an lvalue expression, because it refers to the same entity ...
*p_i; // ... as the entity the expression *p_i in this row refers to.
const int& r_I=7;
r_I; // The expression r_I in this row is an lvalue expression, because it refers to the same entity ...
r_I; // ... as the entity the expression r_I in this row refers to.
f(); // The expression f() in this row is an lvalue expression, because it refers to the same entity ...
i; // ... as the entity the expression f() in this row refers to.
return 0;
}
XValues
E ifadesi yalnızca ve yalnızca xvalue kategorisine aittir.
- dönüş türü döndürülen nesnenin türüne bir rvalue referansı olan örtülü veya açık bir şekilde bir işlevin çağrılmasının sonucu veya
int&& f(){
return 3;
}
int main()
{
f(); // The expression f() belongs to the xvalue category, because f() return type is an rvalue reference to object type.
return 0;
}
- nesne türüne bir rvalue referansına yayın veya
int main()
{
static_cast<int&&>(7); // The expression static_cast<int&&>(7) belongs to the xvalue category, because it is a cast to an rvalue reference to object type.
std::move(7); // std::move(7) is equivalent to static_cast<int&&>(7).
return 0;
}
- nesne ifadesinin bir xvalue olduğu, referans olmayan türde statik olmayan bir veri üyesini belirten bir sınıf üyesi erişim ifadesi veya
struct As
{
int i;
};
As&& f(){
return As();
}
int main()
{
f().i; // The expression f().i belongs to the xvalue category, because As::i is a non-static data member of non-reference type, and the subexpression f() belongs to the xvlaue category.
return 0;
}
- birinci işlenenin xvalue ve ikinci işlenenin veri üyesine işaretçi olduğu bir işaretçi-üye ifadesi.
Yukarıdaki kuralların etkisinin, nesnelere adlandırılmış rvalue referanslarının değer olarak kabul edildiğini ve nesnelere adsız rvalue referanslarının xvalues olarak değerlendirildiğini unutmayın; işlevlere yapılan rvalue referansları, adlandırılmış olsun olmasın, lvalues olarak değerlendirilir.
#include <functional>
struct As
{
int i;
};
As&& f(){
return As();
}
int main()
{
f(); // The expression f() belongs to the xvalue category, because it refers to an unnamed rvalue reference to object.
As&& rr_a=As();
rr_a; // The expression rr_a belongs to the lvalue category, because it refers to a named rvalue reference to object.
std::ref(f); // The expression std::ref(f) belongs to the lvalue category, because it refers to an rvalue reference to function.
return 0;
}
prvalues
E ifadesi yalnızca ve yalnızca E değerine veya xvalue kategorisine ait değilse, değer kategorisine aittir.
struct As
{
void f(){
this; // The expression this is a prvalue expression. Note, that the expression this is not a variable.
}
};
As f(){
return As();
}
int main()
{
f(); // The expression f() belongs to the prvalue category, because it belongs neither to the lvalue nor to the xvalue category.
return 0;
}
KARIŞIK DEĞER KATEGORİLERİ
Başka iki önemli karma değer kategorisi vardır. Bu değer kategorileri rvalue ve glvalue kategorileridir.
SağDeğerler
E ifadesi yalnızca E değeri xvalue kategorisine aitse veya değer kategorisine aitse değer kategorisine aittir.
Bu tanımın, yalnızca E ifadesinin E YET dışında erişilebilir olmasını sağlayan herhangi bir kimliği olmayan bir varlığı ifade etmesi durumunda E ifadesinin değer kategorisine ait olduğu anlamına geldiğini unutmayın.
glvalues
E ifadesi yalnızca E değeri lvalue kategorisine veya xvalue kategorisine aitse glvalue kategorisine aittir.
PRATİK BİR KURAL
Scott Meyer gelmiştir yayınlanan SolDeğerler gelen SağDeğerler ayırt etmek Pratik bir çok faydalı bir kural.
- Bir ifadenin adresini alabilirseniz, ifade bir değerdir.
- Bir ifadenin türü bir değer değeri referansıysa (örneğin, T & veya sabit T & vb.), Bu ifade bir değerdir.
- Aksi takdirde, ifade bir değerdir. Kavramsal olarak (ve tipik olarak da aslında), değerler işlevlerden döndürülen veya örtük tür dönüşümleri yoluyla oluşturulanlar gibi geçici nesnelere karşılık gelir. Çoğu gerçek değerler (örneğin, 10 ve 5.3) de değerlerdir.