A () = A () - neden derleniyor?


85
class A {};

int main() {
 A() = A();
 return 0; 
}

Bu kod neden derleniyor? Atama operatörünün sol tarafına lvalue yerleştirilmesi gerektiğine dair bir hata olmamalı mı? A () l değeri mi? g ++ 4.7 sürümü

Yanıtlar:


88

Yerleşik türler için doğru olursunuz: Yerleşik atama operatörü sol tarafta değiştirilebilir bir değer gerektirir .

Ancak, bu yerleşik işleci değil, sınıf tarafından dolaylı olarak bildirilen aşırı yüklemeyi kullanıyor. Bu bir üye işlevidir, eşdeğerdir

A().operator=(A());

ve üye fonksiyonları rvalues üzerinden çağrılabilir .


7
bu kopya başlatma değil mi?
stardust

13
@Named: Hayır, bu atama başlatma değil.
Mike Seymour

1
@ paul23: Bu doğru ( operator=değil demek istediğini varsayarak operator()), ama soruyla pek bir alakası yok. Örnek, ödevin sonucuyla hiçbir şey yapmaz.
Mike Seymour

3
@ paul23 A()çağırmaz operator(), türde bir nesne oluşturur A.
interjay

3
Bu bir başlangıç ​​olamaz çünkü beyan yok.
Kos

32

Gerçekten istiyorsanız, C ++ 11 ile derlenmemesini sağlayabilirsiniz:

class A {
    template <typename T>
    void operator=(T&&) && = delete; // no op= for rvalues

    // generate other special members normally
    A() = default;
    A(A const&) = default;
    A(A&&) = default;
    ~A() = default;
    // op= only for lvalues
    A& operator=(A&&) & = default;
    A& operator=(A const&) & = default;
};

int main() {
 A() = A(); // error
 return 0; 
}

( canlı örnek )

Çeşitli formların bildirimlerinin sonundaki &ve &&(diğer adıyla ref niteleyiciler) not edin operator=. Bu, bu bildirimlerin sırasıyla lvalues ​​ve rvalues ​​için seçilmesini sağlar. Bununla birlikte, rvalue sürümü, aşırı yük çözümü tarafından seçildiğinde, programın silindiği için kötü biçimlendirilmesine neden olur.

Varsayılan olarak oluşturulan = operatörü, ancak, herhangi bir ref niteleyiciye sahip değildir, yani hem lvalues ​​hem de rvalues ​​için çağrılabilir; bu nedenle sorudaki kod A(), bir r değeri olsa bile derlenir .


1

C ++ derleyicisi, tüm sınıflara varsayılan bir kurucu sağlar, kodunuzla ilgili olarak A () = A () dediğinizde olan budur; sadece yapıcıyı isimsiz bir nesneyle çağırır ve işlev, oluşturulan nesneye (örtük) başvuru döndürür. Bu kadar...

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.