2016-10-07 13 views
6

Ben GCC 7 bulundu garantili kopya elision uygulamıştır ve ben wandbox aşağıdaki kodu çalıştı:Garantili kopya elision ve Nonmoveable {Nonmoveable {}}

#include <iostream> 

struct NonMovable 
{ 
    NonMovable() noexcept = default; 
    NonMovable(NonMovable&&) noexcept = delete; 
    NonMovable& operator=(NonMovable&&) noexcept = delete; 
}; 

NonMovable Make() 
{ 
    return {}; 
} 


int main() 
{ 
    //[[maybe_unused]] const auto x = Make(); 
    //const auto z = NonMovable{}; 
    [[maybe_unused]] const auto y = NonMovable{NonMovable{}}; 
} 

Ve hatayı derlemek var:

prog.cc: In function 'int main()': 
prog.cc:20:60: error: use of deleted function 'NonMovable::NonMovable(NonMovable&&)' 
    [[maybe_unused]] const auto y = NonMovable{NonMovable{}}; 
                  ^
prog.cc:6:5: note: declared here 
    NonMovable(NonMovable&&) noexcept = delete; 
    ^~~~~~~~~~ 

cppreference göre:

In initialization, if the initializer expression is a prvalue and the cv-unqualified version of the source type is the same class as the class of the destination, the initializer expression is used to initialize the destination object:
T x = T(T(T())); // only one call to default constructor of T, to initialize x

yüzden ambalajlama olması gerektiğini düşünüyorum al, const Movable y{};. Sorun nedir?

+0

Görünüşe göre bir GCC hatası. Kod, yeni bir GCC yapısı üzerinde iyi bir derleme yapıyor. – Cu2S

cevap

1

Liste başlatma, ne olacağı konusunda tam bir kontrol sağlamaz. Temel olarak, komite programcının büyük olasılıkla ne yapmak isteyebileceğini ve ilgili anlamları atadığını tahmin etmiştir.

Tam denetime sahip olmak istiyorsanız, liste dışı başlatmayı kullanın. Bunun için test çantan kesinlikle çalışmalı. listelemek-başlatmayı, sonra agrega için uyarsak

, onlar

If T is an aggregate class and the initializer list has a single element of type cv U, where U is T or a class derived from T, the object is initialized from that element (by copy-initialization for copy-list-initialization, or by direct-initialization for direct-list-initialization).

Ayrıca, kudreti demek çünkü, şimdiki taslak ifadeler bunu ve garantili kopyası "elision" geçerlidir düşünüyorum Standardın gelecekteki bir revizyonunda veya agrega olmayanlar için bile hata raporu çözümlerinde istediğinizi elde edin. Sınıfınızın bir toplam olduğuna inanıyorum, bu yüzden derlemesi gerekiyor. Ama belki de burada eksik olduğum bir şey var.

+1

"liste dışı başlatmayı kullan." Const auto y = NonMovable (NonMovable()); '? Eğer öyleyse, bu da işe yaramıyor. –