2011-08-25 43 views
8
string foo() { return "hello"; } 
int main() 
{ 
    //below should be illegal for binding a non-const (lvalue) reference to a rvalue 
    string& tem = foo(); 

    //below should be the correct one as only const reference can be bind to rvalue(most important const) 
    const string& constTem = foo(); 
} 
  1. bir derleme hatası vermek için iyi bir: std::string& tipi std::string
  2. türünde bir std::string& türünün const olmayan referansının geçersiz başlatılması VS2008 en az verirken çok kötü değil derleme uyarısı: uyarı C4239: standart olmayan uzantı kullanılıyor: 'initializing': std::string'den std::string &'a dönüştürme const olmayan bir başvurusu yalnızca bir xvalx39
  3. değerine bağlı olabilir. Sorunlu olanı geliyor - VS2010 (SP1) Herhangi bir hatası veya uyarı OLMADAN, NEDEN ?? !! VS2010'daki rvalue referans rzue ile bağlamak için kullanılabilir ama ben && kullanmıyorum, yerine demo kodu, ben sadece const olmayan lvalue referansı kullanıyordum!

Birisi burada VS2010'un davranışını açıklamama yardım edebilir mi? Bu bir böcek mi? TeşekkürlerBir VS2010 hatası? Bir const OLMADAN, bir const olmayan referansı bağlamak için bir uyarı mı?

+1

Uyarı ayarlarınız nedir? Belki de değişimleri olan ve uygulamalarını değiştirmeyen konfigürasyonunuz mu? –

+0

VS2008'i bir süredir kullanıyorum ama VS2010'u bu yüzden VS10'a yüklüyorum, bu yüzden varsayılan ayarını kullanmalıyım ... – Gob00st

+2

o zaman uyarı eşiğinin sadece yeterince yüksek olmadığını düşünüyorum. '4xxx' aralığında uyarıları etkinleştirmek için '\ W4' kullanın. –

cevap

11

Bu, VS derleyicilerinin bilinen bir sorunudur. Her zaman izin verdiler ve uzantısının uzantısını kaldırmaya yönelik herhangi bir itme yok gibi görünüyorlar.

+0

MS, neden bu yasadışı C++ kullanımına ilk olarak neden izin verdi? Bu özel referans kuralı oldukça eski olmalı (98 veya 03 standart)? – Gob00st

+0

@ Gob00st: Bu, keyfi C++ kısıtlamasını engelleyen bir uzantıdır. Şahsen izin vermemeli, izin verilmemeli ve mevcut * yarısına izin verilen * gerçekten garip bir durum olmalıdır. İzin verilmezse, tüm acı sınıfı ortadan kaldırılır, acı verici olsa bile, İzin Verme özellikleri tam olarak düzeltilebilir. –

+2

@ Gob00st - MS, kurallar düzeltilmeden önce yazılmış eski bir kod içeriyor (ve böylece müşterileri de olabilir).Eski kodu desteklemenin yeni standartlardan daha önemli olduğuna inanıyorlar. Uzantıları kapatmak (ve böylece bazı Windows başlıklarını derleyememek) de mümkündür. –

9

Derleyici, Dil Uzantılarını Devre Dışı Bırak açıkken bir hata ve/W4 adresinde bir uyarı yayınlayacaktır. Ancak, bu kodun kaldırılması daha önce derleme kodunu bozar ve Microsoft bunu yapmak konusunda çok isteksizdir. Bu aynı zamanda SFINAE desteğini de düzeltmeyecekler.

Yani: b.F() için çağrı sırasında b.f noktayı ne kadar bu sorunun çok daha nastier varyantı vardır

+0

Belki de, bu uyarının VS2010'da/W3'ten/W4'e taşındığından bahsetmeye değer. – rustyx

-1

? Yukarıdaki örnek VS2013 varsayılan Hata Ayıklama ayarları ile derlenmiş, çökmeden çalışır ve 3 yazdırır, ancak çok daha karmaşık bir örneğin yığın bozulmasına yol açacağından şüphelenirim. Çalışmıyorsa ve derleyici çalışmasını sağlamak için 'zeki' bir şey yapıyorsa, o zaman gerçekten ne yaptığını tahmin ediyorum:

class Foo { 
    int _val; 
public: 
    Foo(int v) : _val(v) {} 
    void F() { std::cout << _val << std::endl; } 
}; 

class Bar { 
    Foo f; 
public: 
    Bar(Foo&& f) : f(f) {} 
    void F() { f.F(); } 
}; 

int main() { 
    Bar b(Foo(3)); 
    b.F(); 
} 
+0

Aynı sorunun, 'f' bunun yerine bir const başvurusu olması ve bu standardın izin vermesi durumunda da var olduğunu unutmayın. –