2009-05-09 39 views
20

Yaklaşan C++ standardı C++ 0x'un yeni ve yeni özelliklerinden biri, "rvalue referansları" dır. (normalde, geçici yalnızca const referansa bağlı olabilir) geçici değere bağlı şekilde yerleştirilmesi haricinde bir rvalue referans, bir lvalue (normal) referans benzer: YaniNeden C++ 0x rvalue başvurusu varsayılan değil?

void FunctionWithLValueRef(int& a) {...} 
void FunctionWithRValueRef(int&& a) {...} 

int main() { 
    FunctionWithLValueRef(5); // error, 5 is a temporary 
    FunctionWithRValueRef(5); // okay 
} 

, neden yaptılar Normal referanslar üzerindeki kısıtlamaları kaldırmak yerine, temsillere bağlı kalmaları için tamamen yeni bir tür icat edin?

+3

Neden bu 3 oy oyu ama 7 favoriler var merak ediyorum. Hiç oy vermeden bir soruyu desteklediğimi sanmıyorum (oyların dışında kaldığım sürece veya kilitli olmadıkça). – Zifre

+3

Neden birinin bir şekilde düşündüğünü merak ediyorum ve sonra diğerlerinin yaptığı gibi yapmasını bekler. – user534498

+1

Neden "güzel olmanın ve nezaket" vermenin mantıksız bir beklenti olduğunu merak ediyorum. –

cevap

43

Bu çok anlamsız olurdu. İşteki şeyi değiştirirsiniz, ve değişiklik hemen kaybedilir çünkü şey aslında bir geçiciydi. Yeni tipin sebebi, gerçekte bir rengin ve neyin gerçekte olduğuna karar verilebilmesi ihtiyacından kaynaklanmaktadır. Ancak o zaman onları, kullandıkları güzel şeyler için kullanabilirsiniz. 'Bazı rvalue var ve işlev toupper geçirirseniz biz geçici yine bir kullanılıp atılan şey olduğunu biliyorum çünkü Şimdi

string toupper(string && s) { // for nonconst rvalues 
    for(char &c : s) make_uppercase(c); 
    return move(s); // move s into a returned string object 
} 

string toupper(string const& s) { // for the rest 
    // calls the rvalue reference version, by passing 
    // an rvalue copy. 
    return toupper(string(s)); 
} 

, rvalue doğrudan değiştirilebilir, bu yüzden onu ve don değiştirmek sadece lutfen edebilirsiniz kopyalamalısın. Aynı zamanda, hareket gözlemcileri ve hareket atama olarak adlandırılan şey için de aynı gözlem kullanılır. Sağ taraf kopyalanmadı, ancak eşyaları çalındı ​​ve *this'a taşındı.

Eğer rvalues'in const olmayan lvalue referanslarına bağlanabileceğini söyleyecekseniz, bunun bir lvalue (adlandırılmış nesne) veya sondaki bir rengin (geçici) olduğunu anlamanızın hiçbir yolu yoktur.


Muhtemelen daha küçük biliyorum, ama yine de kullanışlı, üye fonksiyonu üzerine lvalue veya rvalue ref-eleme koyabilirsiniz. İşte doğal olarak örtük nesne parametresine rvalue referansların mevcut semantiğini uzanan bir örnek vardır: Artık

struct string { 
    string& operator=(string const& other) & { /* ... */ } 
}; 

, artık diyemeyiz kafa karıştırıcı ve yapım gerçekten değil

string() = "hello"; 

çoğu zaman hissetmek. Yukarıdaki &, atama operatörünün sadece lvalues ​​üzerinde çalıştırılabileceğini söylüyor. Aynı şey && koyarak rıvalılar için yapılabilir.

+1

+1 lvalues ​​/ rvalues ​​ile ilgili son bölüm için sadece üye aramanız için teşekkürler!C++ 0x hakkında çok şey okudum ama bu konuda bir şey görmedim (sanırım son taslakta sanırım ama hepsini okumadım). Bu özellik ile ilgili bazı belgelere işaret edebilir misiniz? – Klaim

+0

İşte güzel bir genel bakış: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1821.htm. Çalışma kağıdında bkz. 8.3.5, 9.3.1 ve 13.3.1. –

+0

Bu cevap için teşekkürler, bu daha net hale getirir. Ben sadece referans değerlerini çok iyi anlamadım. Bu düşündüğümden çok daha anlamlı. – Zifre

12

referans yeni bir tür ekleyerek bir yöntemin iki aşırı yükleri yazmanıza izin verdiğinden:

void CopyFrom(MyClass &&c) 
{ 
    dataMember.swap(c); 
} 

void CopyFrom(const MyClass &c) 
{ 
    dataMember.copyTheHardWay(c); 
} 

aldığı değişkeni değiştirmek için izin verilen referans yeni bir tür kabul versiyonu, yani değişken ISN'de çünkü başka bir yerde kullanılmayacak. Böylece içeriği "çalabilir".

Bu özelliğin eklenmiş olmasının tüm nedeni budur; bir tür referansı tutmak istenen hedefe ulaşamazdı.