2009-01-15 12 views
7

Ben http://code.google.com/p/enhsim kod aşağıdaki satırı derlemek istiyorum: beyan etmezBir nesne bir referansa dönüştürülemez mi?

error: no match for 'operator<<' in 'enh::eout << enh::setw(26)' 

Ama (enh::eout bir örnek olduğu) EnhSimOutput sınıfını:

enh::eout << enh::setw(26); 

gcc aşağıdaki hatayı veriyor

EnhSimOutput& operator<< (setw& p); 

Bu sorunu gideren işlemin bir sürümünü uygularsam, bu sorun giderilir. o değere göre itiraz:

enh::setw wValue(26); 
enh::eout << wValue; 

Sorum şudur: neden gcc ait "by-referans" versiyonunu seçmez

EnhSimOutput& operator<< (setw p); 

yoksa, yani yerel olarak enh::setw nesne oluşturmak durumunda operatör ile başlayacak?

Bu kodu yazan geliştiriciler, onu derlemeyi açıkça yaptı, ancak varsayılan olarak gcc bunu yapmayı reddediyor. Yerel değişken olarak ayrı olarak bildirilen bir nesne ile yerel olarak oluşturulan bir satır içi arasında neden bir fark var?

cevap

13

deneyin. Aslında, bunun gibi zamansal değerler de geçerlidir. Rvalues ​​özel özelliklere sahiptir. Bunlardan biri, adreslerinin alınamayacağı (&enh::setw(26);'un yasadışı olduğu) ve genellikle const olmayan başvurulara bağlayamazlar (bazı temsiller , const olmayan başvurulara bağlanabilir, ancak bunlar özel kurallara tabi olurlar) : Geçici nesneler üzerinde üye işlevlerini çağırmak ve const olmayanlara başvurmak yoluyla istisna nesneleri yakalamak. İkinci durumda, geçici bile bir lvalue) 'dir. referans numarası Sol taraf nesneleri ifade (bu da bir değeri saklamak) ya da işlevler ve değerler, bir nesnenin okunur veya geçiciler tarafından temsil temsil edecek şekilde tasarlanmıştır SağDeğerler:

iki ifadenin tür vardır editörler ve sayım sabitleri. C++ 03'te, bu değerleri değer referansını kabul eden bir fonksiyona aktarabilmek için referansa göre kabul edilebilecekleri bir kural vardır: setw const& p bunu kabul eder. Eğer sigara const (örneğin const enh::setw e(26); kullanılarak yığın üzerinde oluşturulan nesneleri) sabit SolDeğerler disambiguate gelmediğinden dolayı biraz talihsiz

EnhSimOutput& operator<< (setw const& p); 

ya: Yani böyle operatörünüze beyan etmek zorunda olur const rvalues ​​(const olmayan bir geçici olan enh::setw(26); gibi). Ayrıca, eğer buna göre giderseniz, parametre üzerinde const olmayan üye işlevleri çağırdı, çünkü bir const-const. Bu nedenle, C++ 1x, sonraki C++ sürümü, rvalue referansları olan olarak adlandırılan yeni bir referans türü sunar.


Microsoft Visual C++ derleyici olmayan const referanslar SağDeğerler bağlar, ancak (bunu göstermek için en azından uyarı seviyesini 4 kullanmak zorunda) Ancak bunu yaparken, bir uyarı verir. Bu talihsiz, çünkü standart uyum içinde daha katı olan diğer derleyicilere taşınırken sorunlar yükselir.

+0

Operatörün bir const referansına değiştirilmesi sorunu hassas bir şekilde düzeltir. Rvalues ​​hakkında bilgi için teşekkürler. Kodun neden başka biri için derlenmiş olduğunu bilmiyorum. Proje Windows için tasarlandı ... belki hepsi bir * öksürük * komplikasyonsuz derleyici kullanıyor. Fikrim yok. –

+0

litb: "Cümleninizde" referans-to-const "kastettiğinizi düşünüyorum." Ayrıca, eğer buna katılırsanız, parametre üzerinde const olmayan üye fonksiyonlarını çağırmış olamaz, çünkü bu bir non-cons-to-consconst. " –

+0

Matt: MS Visual C++ 'nin eski sürümleri, geçici olmayanları const olmayan yapısına hatalı olarak bağlar. Bu MSVC++ 2005'te düzeltildiğini düşünüyorum. –

3

Benim tahminim, EnhSimOutput& operator<< (setw& p);, yerleşik olmayan başvuruya göre geçer, ancak 26 değeri, değiştirilememesi anlamında "const" olur. EnhSimOutput& operator<< (const setw& p);

bunu ayarlamayı deneyin veya değer enh::setw(26); bir rvalue olduğunu

int nNumber = 26; 
enh::eout << enh::setw(nNumber); 
+0

-1, çünkü sorunun bir literal olmakla ilgisi yoktur. Sorun şu ki 'enh :: setw (sayı)' geçici bir durumdur ve bu nedenle bir const olmayan referansa bağlı olamaz. –