18

çalışmaz ile sınıf initializaton böyle) standardından:C++ 11: "= {}" C++ 11 bir "bağ ya da-eşit-başlatıcı" kullanılarak sınıfının başlatma yapabilir (kelime olarak açık kurucu

struct Foo 
{ 
    /*explicit*/ Foo(int) {} 
}; 

struct Bar 
{ 
    Foo foo = { 42 }; 
}; 

Ama un-yorum explicit, artık derler eğer. GCC 4.7 ve 4.9 bunu söyler: Bu şaşırtıcı olduğunu buldum. Gerçekten bu kodun derleme yapmadığı C++ 11 standardının amacı mı? Foo foo { 42 }; ama ben şahsen daha zor bu on yıllardır = ile forma kullanılmıştır insanlara anlatmaya bulmak ve standart bir "bağ-veya-eşit-başlatıcısı" atıfta beri var:

= düzelir Çıkarma Bu senaryoda iyi eski yolun neden çalışmadığı belli değil.

+2

'{}' başlatıcı sözdizimi bir tür kesmek gibidir ve bu –

+0

gibi garip köşe durumları bir demet vardır Ben çift köşeli ayraç kullanmak zorunda olduğunu düşündüm - Foo foo = {{42}}; –

+0

@CarlBurnett: Çift köşeli ayraçlar aynı şeyi tek parantez gibi görünüyor - hala bozuk. –

cevap

12

Bu mantığı da açıklanmaktadır olamaz, ama ben bariz tekrarlayabilirsiniz.

Ben bu şaşırtıcı buldum. Bu kodun derlenmediği C++ 11 standardının amacı nedir? Açık bir kurucu seçilirse
kopya-list-başlatma olarak

§13.3.1.7

, başlatma kötü oluşturulur.


Çıkarma = düzelir: Ben şahsen yıllardır = ile forma kullanılmıştır insanlara anlatmak bu zor bulmak ve standart bir atıfta beri Foo foo { 42 }; ama eski güzel yolu bu senaryoda neden çalışmıyor "ayracı-veya-eşit-başlatıcı" değil açıktır.

Foo foo { 42 } eşittir işareti oysa copy-list-initialization yapar (parantez ile), direct initialization olup. derleme copy-initialization (parantez olmadan eşittir işareti) için başarısız çünkü başka cevap nedenleri, o zaman o da kopyalama liste başlatılması için başarısız olması şaşırtıcı olmamalıdır, ancak iki farklı nedenlerle başarısız.

cppreference:

Doğrudan başlatma kopyalamaya karşı başlatma daha hoşgörülü geçerli: kopya-başlatma sadece, açık olmayan kurucular ve kullanıcı tanımlı dönüşüm fonksiyonlarını dikkate direkt başlatma tüm Kurucular gördüğü süre ve örtük dönüşüm dizileri.

Ve explicit specifier üzerindeki sayfa:

Kurucular ve belirtir örtük dönüşüm ya kopya-başlatma izin vermez dönüşüm operatörleri (C++ 11 beri). kopyalamaya listesi başlatılması için Öte yandan

:

T nesne = {ARG1, arg2, ...};

10 (10)

) eşittir sağ tarafında iki aşamalı olarak,

  • Aksi takdirde, T kurucular olarak kabul edilir (benzer kopya başlatma) oturum:

    önceki aşamada bir eşleşme üretmiyorsa, T tüm kurucular sınırlama sıkıştırılabilmekte-init-listesinin elemanları grubundan oluşur bağımsız değişkenler grubu karşı aşırı çözünürlükte
    • katılma sadece olmayan daralma dönüşüm izin verilir. Bu aşama bir kopya listesi başlatılması için en iyi eşleşme olarak açık bir yapıcı üretirse , derleme (not, basit kopya-başlatma içinde, açık kurucular hiç dikkate alınmamıştır) başarısız

What could go wrong if copy-list-initialization allowed explicit constructors?'da açıklandığı gibi, açık yapıcı seçildiğinden, ancak kullanılmasına izin verilmediğinden derleme başarısız olur.

7

widget w = {x};

Buna “kopya listesi başlatması” denir. Bu, widget ile aynıdır {x}; Açık yapıcılar hariç kullanılamaz. Yalnızca tek bir kurucunun çağrılması garanti edilir. http://herbsutter.com/2013/05/09/gotw-1-solution/

itibaren

Bir nesneyi ilklendirebilirsiniz çeşitli şekillerde konusunda daha ayrıntılı bir tartışma için maddenin kalanını bakın. Foo(int)explicit olduğunu

11

, o zaman bu da derlenmeyecektir:

"on yıllardır = ile forma kullanılmış olan kişiler" Yani
Foo foo = 42; 

o forma bir sürpriz olmayacak {} ile ya da derleme değil.

+5

'Foo foo = 42' * örtülü olarak * foo'yu başlatmak için bir' Foo 'prvalue oluşturur. Bu Foo foo = {42} 'için geçerli değildir, bu da * örtülü olarak“ Foo ”yaratmaz. – dyp

+0

@dyp ile birlikteyim: Neden Foo foo = 42' nin işe yaramayacağını anlıyorum ve bununla sorun yok. Foo foo = {42} 'nin neden çalışmadığı konusunda hala şaşkınım. Burada başka bir cevaptan da görüldüğü gibi bu, standardın amaçlandığı ya da en azından bekleneceği gibi görünse de ... kötü görünüyor. –