2015-09-03 13 views
6

Sadece bana operator+ & eşinin rt değerleri için this üzerinde çalışabileceği; yani bir sınıf C göz önüne alındığında, bunu yapmak mümkündür: Bu sadece yerinde geçici değerleri değiştirerek kopya önleyecekOperatörleri, geçici durumları önlemek için ref-niteleyici ile aşırı yüklemek mantıklı mıdır?

class C { 
    // ... 
    C operator-(const C& rhs) const & { 
     C result = *this; 
     result -= rhs; 
     return result; 
    } 
    C&& operator-(const C& rhs) && { 
     *this -= rhs; 
     return std::move(*this); 
    } 
}; 

.

Beklediğim gibi performans sergiliyor mu? Makul bir optimizasyon mu yoksa derleyici aynı derecede hızlı kod oluşturuyor mu?

+0

İlk sürümde zaten kopyalama ellision alabilirsiniz. Yani ikincisinin gerekli olduğundan emin değilim (eğer hiç işe yaramıyorsa, seni götüne sokar gibi hissederdim ama yanılıyor olabilirim) – Borgleader

+0

Evet, kopya seçiminin benzer performansa yol açabileceğini hissediyorum. .. Ama sürümümün beni henüz kıçımda nasıl ısırdığını göremiyorum. (Ancak emin değilim, bu yüzden soru.) –

+0

Nesne yaşam boyu sorunları. C && c = C() - some_C; 've' c' sarkan. –

cevap

5

en biz sadece std::string sarmak ve operator+ basitleştirilmiş versiyonunu yapmak varsayalım: aldığımızda

struct C { 
    std::string val; 

    C&& operator+(const C& rhs) && { 
     val += rhs.val; 
     return std::move(*this); 
    } 

    std::string::iterator begin() { return val.begin(); } 
    std::string::iterator end() { return val.end(); } 
}; 

, bu iyi çalışır:

for (char c : C{"hello"}) { .. } 

menzil-için ifadenin ömrünü uzatacaktır Geçici, yani iyiyiz. Ancak, bu göz önünde bulundurun:

for (char c : C{"hello"} + C{"goodbye"}) { .. } 

Biz etkili bir şekilde var:

auto&& __range = C{"hello"}.operator+(C{"goodbye"}); 

Burada bir referansa geçici bağlayıcı değiliz. Bir referansı bağlarız. Nesne ömrünü uzatmaz, çünkü bu bir nesne değildir. Yani sarkan bir referansımız ve tanımlanmamış davranışlarımız var. Bu, bu işe beklenebilir kullanıcılara çok şaşırtıcı olurdu:

for (char c : std::string{"hello"} + std::string{"goodbye"}) { .. } 

Bir değer döndürmek zorundayız: (şimdi geçici uzantısı olan gibi) bu sorunu çözer

C operator+(const C& rhs) && { 
    val += rhs.val; 
    return std::move(*this); 
} 

, ve eğer nesneleri hareket ettirmek onları kopyalamaktan daha ucuzsa, bu bir kazançtır.

İlgili konular