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:
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 .
operator=değil demek istediğini varsayarak operator()), ama soruyla pek bir alakası yok. Örnek, ödevin sonucuyla hiçbir şey yapmaz.
A()çağırmaz operator(), türde bir nesne oluşturur A.
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 .
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...