Kompiler akan mengubah literal ganda 3.0menjadi float untuk Anda. Hasil akhirnya tidak bisa dibedakan float a = 3.0f.
David Heffernan
6
@EdHeal: Ya, tetapi tidak terlalu relevan dengan pertanyaan ini, yaitu tentang aturan C ++.
Keith Thompson
20
Yah, setidaknya Anda membutuhkan ;setelah.
Hot Licks
3
10 suara negatif dan tidak banyak di komentar untuk menjelaskannya, sangat mengecewakan. Ini adalah pertanyaan pertama OP dan jika orang merasa ini layak untuk 10 suara negatif, harus ada beberapa penjelasan. Ini adalah pertanyaan yang valid dengan implikasi yang tidak jelas dan banyak hal menarik untuk dipelajari dari jawaban dan komentar.
Shafik Yaghmour
3
@HotLicks ini bukan tentang perasaan buruk atau baik, yakin itu mungkin tampak tidak adil tapi itulah hidup, bagaimanapun juga itu adalah poin unicorn. Dowvote tentunya bukan untuk membatalkan suara positif yang tidak Anda sukai seperti suara positif tidak untuk membatalkan suara negatif yang tidak Anda sukai. Jika orang merasa pertanyaannya bisa diperbaiki, tentunya penanya yang baru pertama kali harus mendapatkan umpan balik. Saya tidak melihat alasan apa pun untuk tidak memilih tetapi saya ingin tahu mengapa orang lain melakukannya meskipun mereka bebas untuk tidak mengatakannya.
Shafik Yaghmour
Jawaban:
159
Ini bukan kesalahan untuk dideklarasikan float a = 3.0: jika Anda melakukannya, kompilator akan mengubah double literal 3.0 menjadi float untuk Anda.
Namun, Anda harus menggunakan notasi literal float dalam skenario tertentu.
Untuk alasan kinerja:
Secara khusus, pertimbangkan:
floatfoo(float x){ return x * 0.42; }
Di sini kompilator akan mengeluarkan konversi (yang akan Anda bayarkan saat runtime) untuk setiap nilai yang dikembalikan. Untuk menghindarinya, Anda harus menyatakan:
floatfoo(float x){ return x * 0.42f; } // OK, no conversion required
Untuk menghindari bug saat membandingkan hasil:
misalnya perbandingan berikut gagal:
float x = 4.2;
if (x == 4.2)
std::cout << "oops"; // Not executed!
Kita bisa memperbaikinya dengan notasi literal float:
Pada poin 1 42adalah integer, yang secara otomatis dipromosikan menjadi float(dan itu akan terjadi pada waktu kompilasi di kompiler yang layak), jadi tidak ada penalti performa. Mungkin maksudmu seperti itu 42.0.
Matteo Italia
@MatteoItalia, ya maksud saya 42.0 ofc (diedit, terima kasih)
quantdev
2
Mengonversi @ChristianHackl 4.2ke 4.2fmungkin memiliki efek samping menyetel FE_INEXACTflag, bergantung pada compiler dan sistem, dan beberapa (memang sedikit) program peduli tentang operasi floating-point mana yang tepat, dan mana yang tidak, dan menguji flag itu . Ini berarti bahwa transformasi waktu kompilasi yang jelas dan sederhana mengubah perilaku program.
6
float foo(float x) { return x*42.0; }dapat disusun menjadi perkalian presisi tunggal, dan dikompilasi oleh Clang terakhir kali saya mencoba. Namun float foo(float x) { return x*0.1; }tidak dapat dikompilasi menjadi perkalian presisi tunggal. Mungkin sedikit terlalu optimis sebelum tambalan ini, tetapi setelah tambalan itu seharusnya hanya menggabungkan konversi-double_precision_op-conversion ke single_precision_op ketika hasilnya selalu sama. article.gmane.org/gmane.comp.compilers.llvm.cvs/167800/match=
Pascal Cuoq
1
Jika seseorang ingin menghitung nilai yang sepersepuluh someFloat, ekspresi tersebut someFloat * 0.1akan menghasilkan hasil yang lebih akurat daripada someFloat * 0.1f, sementara dalam banyak kasus lebih murah daripada pembagian floating-point. Misalnya, (float) (167772208.0f * 0.1) akan dibulatkan dengan benar ke 16777220 daripada 16777222. Beberapa kompiler mungkin mengganti doubleperkalian untuk pembagian floating-point, tetapi untuk yang tidak (aman untuk banyak meskipun tidak semua nilai ) penggandaan mungkin merupakan pengoptimalan yang berguna, tetapi hanya jika dilakukan dengan doubletimbal balik.
supercat
22
Kompilator akan mengubah salah satu literal berikut menjadi float, karena Anda mendeklarasikan variabel sebagai float.
float a = 3; // converted to floatfloat b = 3.0; // converted to floatfloat c = 3.0f; // float
Ini akan menjadi masalah jika Anda menggunakan auto(atau metode pengurangan jenis lainnya), misalnya:
auto d = 3; // intauto e = 3.0; // doubleauto f = 3.0f; // float
Jenis juga disimpulkan saat menggunakan templat, jadi autobukan satu-satunya kasus.
Shafik Yaghmour
14
Literal floating point tanpa sufiks adalah tipe double , ini tercakup dalam draf bagian standar C ++ 2.14.4Literal mengambang :
[...] Jenis literal mengambang adalah ganda kecuali secara eksplisit ditentukan oleh sufiks. [...]
jadi itu kesalahan untuk menetapkan 3.0suatu literal ganda untuk mengapung ?:
float a = 3.0
Tidak, tidak, itu akan dikonversi, yang dibahas di bagian 4.8Konversi titik mengambang :
Nilai pr dari jenis titik mengambang dapat diubah menjadi nilai pr dari jenis titik mengambang lainnya. Jika nilai sumber dapat secara tepat direpresentasikan dalam jenis tujuan, hasil konversinya adalah representasi yang tepat. Jika nilai sumber berada di antara dua nilai tujuan yang berdekatan, hasil konversi adalah pilihan yang ditentukan penerapan dari salah satu nilai tersebut. Jika tidak, perilakunya tidak ditentukan.
Ini berarti bahwa konstanta ganda dapat secara implisit (yaitu, diam-diam) diubah menjadi konstanta float, bahkan jika hal tersebut kehilangan presisi (yaitu, data). Ini diizinkan untuk tetap karena kompatibilitas C dan alasan kegunaan, tetapi perlu diingat saat Anda melakukan pekerjaan floating-point.
Kompiler kualitas akan memperingatkan Anda jika Anda mencoba melakukan sesuatu yang perilaku tidak terdefinisi, yaitu menempatkan kuantitas ganda ke dalam float yang kurang dari nilai minimum, atau lebih besar dari maksimum, yang dapat diwakili oleh float. Kompiler yang sangat baik akan memberikan peringatan opsional jika Anda mencoba melakukan sesuatu yang mungkin didefinisikan tetapi dapat kehilangan informasi, yaitu menempatkan kuantitas ganda ke dalam pelampung yang berada di antara nilai minimum dan maksimum yang dapat direpresentasikan oleh pelampung, tetapi yang tidak dapat direpresentasikan persis sebagai pelampung.
Jadi ada peringatan untuk kasus umum yang harus Anda waspadai.
Dari segi kepraktisan, dalam hal ini kemungkinan besar hasilnya akan sama walaupun secara teknis ada konversi, kita bisa melihatnya dengan mencoba kode berikut pada godbolt :
dan kami melihat bahwa hasil untuk func1dan func2identik, menggunakan keduanya clangdan gcc:
func1():
movss xmm0, DWORD PTR .LC0[rip]
ret
func2():
movss xmm0, DWORD PTR .LC0[rip]
ret
Seperti yang ditunjukkan Pascal dalam komentar ini, Anda tidak akan selalu dapat mengandalkan ini. Menggunakan 0.1dan 0.1fmasing - masing menyebabkan perakitan yang dihasilkan berbeda karena konversi sekarang harus dilakukan secara eksplisit. Kode berikut:
floatfunc1(float x ){
return x*0.1; // a double literal
}
floatfunc2(float x){
return x*0.1f ; // a float literal
}
Terlepas dari apakah Anda dapat menentukan apakah konversi akan berdampak pada kinerja atau tidak, menggunakan jenis dokumen yang benar lebih baik untuk tujuan Anda. Menggunakan konversi eksplisit misalnya static_castjuga membantu untuk memperjelas bahwa konversi itu dimaksudkan bukan tidak disengaja, yang mungkin menandakan bug atau potensi bug.
Catatan
Seperti yang ditunjukkan supercat, perkalian dengan eg 0.1dan 0.1ftidak ekivalen. Saya hanya akan mengutip komentar karena itu sangat bagus dan ringkasannya mungkin tidak akan adil:
Misalnya, jika f sama dengan 100000224 (yang dapat direpresentasikan secara tepat sebagai pelampung), mengalikannya dengan sepersepuluh akan menghasilkan hasil yang membulatkan ke bawah menjadi 10000022, tetapi mengalikan dengan 0,1f malah akan menghasilkan hasil yang keliru membulatkan menjadi 10000023 Jika tujuannya adalah untuk membagi dengan sepuluh, perkalian dengan konstanta ganda 0,1 kemungkinan akan lebih cepat daripada pembagian dengan 10f, dan lebih tepat daripada perkalian dengan 0,1f.
Poin awal saya adalah untuk mendemonstrasikan contoh palsu yang diberikan dalam pertanyaan lain tetapi ini menunjukkan masalah halus dapat ada dalam contoh mainan.
Mungkin perlu dicatat bahwa ekspresi f = f * 0.1;dan f = f * 0.1f;melakukan hal yang berbeda . Misalnya, jika fsama dengan 100000224 (yang dapat direpresentasikan secara persis sebagai a float), mengalikannya dengan sepersepuluh akan menghasilkan hasil yang dibulatkan menjadi 10000022, tetapi mengalikan dengan 0,1f akan menghasilkan hasil yang keliru membulatkan menjadi 10000023. Jika tujuannya adalah untuk membagi dengan sepuluh, perkalian dengan doublekonstanta 0,1 kemungkinan akan lebih cepat daripada pembagian dengan 10f, dan lebih tepat daripada perkalian dengan 0.1f.
supercat
@supercat terima kasih atas contoh yang bagus, saya mengutip Anda secara langsung, silakan edit sesuai keinginan Anda.
Shafik Yaghmour
4
Ini bukan kesalahan dalam artian kompilator akan menolaknya, tetapi ini adalah kesalahan dalam artian mungkin bukan itu yang Anda inginkan.
Seperti yang dinyatakan buku Anda dengan benar, 3.0adalah nilai tipe double. Ada konversi implisit dari doublemenjadi float, begitu float a = 3.0;juga definisi variabel yang valid.
Namun, setidaknya secara konseptual, ini melakukan konversi yang tidak perlu. Bergantung pada kompilernya, konversi dapat dilakukan pada waktu kompilasi, atau mungkin disimpan untuk run time. Alasan yang valid untuk menyimpannya untuk waktu proses adalah bahwa konversi floating-point sulit dan mungkin memiliki efek samping yang tidak terduga jika nilai tidak dapat direpresentasikan dengan tepat, dan tidak selalu mudah untuk memverifikasi apakah nilai dapat direpresentasikan dengan tepat.
3.0f menghindari masalah itu: meskipun secara teknis, kompilator masih diperbolehkan menghitung konstanta pada waktu proses (selalu demikian), di sini, sama sekali tidak ada alasan mengapa kompilator mungkin melakukan itu.
Memang, dalam kasus kompilator silang, akan sangat tidak tepat jika konversi dilakukan pada waktu kompilasi, karena itu akan terjadi pada platform yang salah.
pengguna207421
2
Meskipun bukan merupakan kesalahan, namun itu sedikit ceroboh. Anda tahu Anda menginginkan pelampung, jadi inisialisasi dengan pelampung. Programmer lain mungkin datang dan tidak yakin bagian mana dari deklarasi yang benar, jenis atau penginisialisasi. Mengapa keduanya tidak benar?
mengapung Jawaban = 42.0f;
Ketika Anda mendefinisikan variabel, itu diinisialisasi dengan penginisialisasi yang disediakan. Ini mungkin memerlukan konversi nilai penginisialisasi ke jenis variabel yang sedang diinisialisasi. Itulah yang terjadi ketika Anda mengatakan float a = 3.0;: Nilai penginisialisasi dikonversi menjadi float, dan hasil konversi menjadi nilai awal a.
Biasanya tidak masalah, tetapi tidak ada salahnya menulis 3.0funtuk menunjukkan bahwa Anda sadar akan apa yang Anda lakukan, dan terutama jika Anda ingin menulis auto a = 3.0f.
yang menunjukkan, ukuran 3.2f diambil sebagai 4 byte pada mesin 32-bit dimana 3,2 diartikan sebagai nilai ganda yang mengambil 8 byte pada mesin 32-bit. Ini harus memberikan jawaban yang Anda cari.
Itu menunjukkan bahwa doubledan floatberbeda, itu tidak menjawab apakah Anda dapat menginisialisasi a floatdari literal ganda
Jonathan Wakely
tentu saja Anda dapat menginisialisasi pelampung dari nilai ganda yang tunduk pada pemotongan data, jika berlaku
Dr. Debasish Jana
4
Ya saya tahu, tapi itu pertanyaan OP, jadi jawaban Anda gagal menjawabnya, meskipun mengaku memberikan jawabannya!
Jonathan Wakely
0
Penyusun menyimpulkan jenis yang paling pas dari literal, atau setidaknya apa yang menurutnya paling pas. Artinya agak kehilangan efisiensi atas presisi, yaitu menggunakan double sebagai pengganti float. Jika ragu, gunakan brace-intializers untuk membuatnya eksplisit:
auto d = double{3}; // make a doubleauto f = float{3}; // make a floatauto i = int{3}; // make a int
Ceritanya menjadi lebih menarik jika Anda menginisialisasi dari variabel lain di mana aturan konversi tipe berlaku: Meskipun legal untuk menyusun bentuk ganda literal, itu tidak dapat dikonstruksi dari int tanpa kemungkinan penyempitan:
auto xxx = double{i} // warning ! narrowing conversion of 'i' from 'int' to 'double'
3.0
menjadi float untuk Anda. Hasil akhirnya tidak bisa dibedakanfloat a = 3.0f
.;
setelah.Jawaban:
Ini bukan kesalahan untuk dideklarasikan
float a = 3.0
: jika Anda melakukannya, kompilator akan mengubah double literal 3.0 menjadi float untuk Anda.Namun, Anda harus menggunakan notasi literal float dalam skenario tertentu.
Untuk alasan kinerja:
Secara khusus, pertimbangkan:
float foo(float x) { return x * 0.42; }
Di sini kompilator akan mengeluarkan konversi (yang akan Anda bayarkan saat runtime) untuk setiap nilai yang dikembalikan. Untuk menghindarinya, Anda harus menyatakan:
float foo(float x) { return x * 0.42f; } // OK, no conversion required
Untuk menghindari bug saat membandingkan hasil:
misalnya perbandingan berikut gagal:
float x = 4.2; if (x == 4.2) std::cout << "oops"; // Not executed!
Kita bisa memperbaikinya dengan notasi literal float:
if (x == 4.2f) std::cout << "ok !"; // Executed!
(Catatan: tentu saja, ini bukan cara Anda membandingkan angka float atau double untuk persamaan secara umum )
Untuk memanggil fungsi kelebihan beban yang benar (untuk alasan yang sama):
Contoh:
void foo(float f) { std::cout << "\nfloat"; } void foo(double d) { std::cout << "\ndouble"; } int main() { foo(42.0); // calls double overload foo(42.0f); // calls float overload return 0; }
Seperti dicatat oleh Cyber , dalam konteks deduksi tipe, diperlukan untuk membantu kompilator menyimpulkan
float
:Dalam kasus
auto
:auto d = 3; // int auto e = 3.0; // double auto f = 3.0f; // float
Dan serupa, dalam kasus pengurangan jenis template:
void foo(float f) { std::cout << "\nfloat"; } void foo(double d) { std::cout << "\ndouble"; } template<typename T> void bar(T t) { foo(t); } int main() { bar(42.0); // Deduce double bar(42.0f); // Deduce float return 0; }
Demo langsung
sumber
42
adalah integer, yang secara otomatis dipromosikan menjadifloat
(dan itu akan terjadi pada waktu kompilasi di kompiler yang layak), jadi tidak ada penalti performa. Mungkin maksudmu seperti itu42.0
.4.2
ke4.2f
mungkin memiliki efek samping menyetelFE_INEXACT
flag, bergantung pada compiler dan sistem, dan beberapa (memang sedikit) program peduli tentang operasi floating-point mana yang tepat, dan mana yang tidak, dan menguji flag itu . Ini berarti bahwa transformasi waktu kompilasi yang jelas dan sederhana mengubah perilaku program.float foo(float x) { return x*42.0; }
dapat disusun menjadi perkalian presisi tunggal, dan dikompilasi oleh Clang terakhir kali saya mencoba. Namunfloat foo(float x) { return x*0.1; }
tidak dapat dikompilasi menjadi perkalian presisi tunggal. Mungkin sedikit terlalu optimis sebelum tambalan ini, tetapi setelah tambalan itu seharusnya hanya menggabungkan konversi-double_precision_op-conversion ke single_precision_op ketika hasilnya selalu sama. article.gmane.org/gmane.comp.compilers.llvm.cvs/167800/match=someFloat
, ekspresi tersebutsomeFloat * 0.1
akan menghasilkan hasil yang lebih akurat daripadasomeFloat * 0.1f
, sementara dalam banyak kasus lebih murah daripada pembagian floating-point. Misalnya, (float) (167772208.0f * 0.1) akan dibulatkan dengan benar ke 16777220 daripada 16777222. Beberapa kompiler mungkin menggantidouble
perkalian untuk pembagian floating-point, tetapi untuk yang tidak (aman untuk banyak meskipun tidak semua nilai ) penggandaan mungkin merupakan pengoptimalan yang berguna, tetapi hanya jika dilakukan dengandouble
timbal balik.Kompilator akan mengubah salah satu literal berikut menjadi float, karena Anda mendeklarasikan variabel sebagai float.
float a = 3; // converted to float float b = 3.0; // converted to float float c = 3.0f; // float
Ini akan menjadi masalah jika Anda menggunakan
auto
(atau metode pengurangan jenis lainnya), misalnya:auto d = 3; // int auto e = 3.0; // double auto f = 3.0f; // float
sumber
auto
bukan satu-satunya kasus.Literal floating point tanpa sufiks adalah tipe double , ini tercakup dalam draf bagian standar C ++
2.14.4
Literal mengambang :jadi itu kesalahan untuk menetapkan
3.0
suatu literal ganda untuk mengapung ?:float a = 3.0
Tidak, tidak, itu akan dikonversi, yang dibahas di bagian
4.8
Konversi titik mengambang :Kami dapat membaca lebih detail tentang implikasi dari ini di GotW # 67: ganda atau tidak ada yang mengatakan:
Jadi ada peringatan untuk kasus umum yang harus Anda waspadai.
Dari segi kepraktisan, dalam hal ini kemungkinan besar hasilnya akan sama walaupun secara teknis ada konversi, kita bisa melihatnya dengan mencoba kode berikut pada godbolt :
#include <iostream> float func1() { return 3.0; // a double literal } float func2() { return 3.0f ; // a float literal } int main() { std::cout << func1() << ":" << func2() << std::endl ; return 0; }
dan kami melihat bahwa hasil untuk
func1
danfunc2
identik, menggunakan keduanyaclang
dangcc
:func1(): movss xmm0, DWORD PTR .LC0[rip] ret func2(): movss xmm0, DWORD PTR .LC0[rip] ret
Seperti yang ditunjukkan Pascal dalam komentar ini, Anda tidak akan selalu dapat mengandalkan ini. Menggunakan
0.1
dan0.1f
masing - masing menyebabkan perakitan yang dihasilkan berbeda karena konversi sekarang harus dilakukan secara eksplisit. Kode berikut:float func1(float x ) { return x*0.1; // a double literal } float func2(float x) { return x*0.1f ; // a float literal }
hasil perakitan berikut:
func1(float): cvtss2sd %xmm0, %xmm0 # x, D.31147 mulsd .LC0(%rip), %xmm0 #, D.31147 cvtsd2ss %xmm0, %xmm0 # D.31147, D.31148 ret func2(float): mulss .LC2(%rip), %xmm0 #, D.31155 ret
Terlepas dari apakah Anda dapat menentukan apakah konversi akan berdampak pada kinerja atau tidak, menggunakan jenis dokumen yang benar lebih baik untuk tujuan Anda. Menggunakan konversi eksplisit misalnya
static_cast
juga membantu untuk memperjelas bahwa konversi itu dimaksudkan bukan tidak disengaja, yang mungkin menandakan bug atau potensi bug.Catatan
Seperti yang ditunjukkan supercat, perkalian dengan eg
0.1
dan0.1f
tidak ekivalen. Saya hanya akan mengutip komentar karena itu sangat bagus dan ringkasannya mungkin tidak akan adil:Poin awal saya adalah untuk mendemonstrasikan contoh palsu yang diberikan dalam pertanyaan lain tetapi ini menunjukkan masalah halus dapat ada dalam contoh mainan.
sumber
f = f * 0.1;
danf = f * 0.1f;
melakukan hal yang berbeda . Misalnya, jikaf
sama dengan 100000224 (yang dapat direpresentasikan secara persis sebagai afloat
), mengalikannya dengan sepersepuluh akan menghasilkan hasil yang dibulatkan menjadi 10000022, tetapi mengalikan dengan 0,1f akan menghasilkan hasil yang keliru membulatkan menjadi 10000023. Jika tujuannya adalah untuk membagi dengan sepuluh, perkalian dengandouble
konstanta 0,1 kemungkinan akan lebih cepat daripada pembagian dengan10f
, dan lebih tepat daripada perkalian dengan0.1f
.Ini bukan kesalahan dalam artian kompilator akan menolaknya, tetapi ini adalah kesalahan dalam artian mungkin bukan itu yang Anda inginkan.
Seperti yang dinyatakan buku Anda dengan benar,
3.0
adalah nilai tipedouble
. Ada konversi implisit daridouble
menjadifloat
, begitufloat a = 3.0;
juga definisi variabel yang valid.Namun, setidaknya secara konseptual, ini melakukan konversi yang tidak perlu. Bergantung pada kompilernya, konversi dapat dilakukan pada waktu kompilasi, atau mungkin disimpan untuk run time. Alasan yang valid untuk menyimpannya untuk waktu proses adalah bahwa konversi floating-point sulit dan mungkin memiliki efek samping yang tidak terduga jika nilai tidak dapat direpresentasikan dengan tepat, dan tidak selalu mudah untuk memverifikasi apakah nilai dapat direpresentasikan dengan tepat.
3.0f
menghindari masalah itu: meskipun secara teknis, kompilator masih diperbolehkan menghitung konstanta pada waktu proses (selalu demikian), di sini, sama sekali tidak ada alasan mengapa kompilator mungkin melakukan itu.sumber
Meskipun bukan merupakan kesalahan, namun itu sedikit ceroboh. Anda tahu Anda menginginkan pelampung, jadi inisialisasi dengan pelampung.
Programmer lain mungkin datang dan tidak yakin bagian mana dari deklarasi yang benar, jenis atau penginisialisasi. Mengapa keduanya tidak benar?
mengapung Jawaban = 42.0f;
sumber
Ketika Anda mendefinisikan variabel, itu diinisialisasi dengan penginisialisasi yang disediakan. Ini mungkin memerlukan konversi nilai penginisialisasi ke jenis variabel yang sedang diinisialisasi. Itulah yang terjadi ketika Anda mengatakan
float a = 3.0;
: Nilai penginisialisasi dikonversi menjadifloat
, dan hasil konversi menjadi nilai awala
.Biasanya tidak masalah, tetapi tidak ada salahnya menulis
3.0f
untuk menunjukkan bahwa Anda sadar akan apa yang Anda lakukan, dan terutama jika Anda ingin menulisauto a = 3.0f
.sumber
Jika Anda mencoba yang berikut ini:
std::cout << sizeof(3.2f) <<":" << sizeof(3.2) << std::endl;
Anda akan mendapatkan keluaran sebagai:
4:8
yang menunjukkan, ukuran 3.2f diambil sebagai 4 byte pada mesin 32-bit dimana 3,2 diartikan sebagai nilai ganda yang mengambil 8 byte pada mesin 32-bit. Ini harus memberikan jawaban yang Anda cari.
sumber
double
danfloat
berbeda, itu tidak menjawab apakah Anda dapat menginisialisasi afloat
dari literal gandaPenyusun menyimpulkan jenis yang paling pas dari literal, atau setidaknya apa yang menurutnya paling pas. Artinya agak kehilangan efisiensi atas presisi, yaitu menggunakan double sebagai pengganti float. Jika ragu, gunakan brace-intializers untuk membuatnya eksplisit:
auto d = double{3}; // make a double auto f = float{3}; // make a float auto i = int{3}; // make a int
Ceritanya menjadi lebih menarik jika Anda menginisialisasi dari variabel lain di mana aturan konversi tipe berlaku: Meskipun legal untuk menyusun bentuk ganda literal, itu tidak dapat dikonstruksi dari int tanpa kemungkinan penyempitan:
auto xxx = double{i} // warning ! narrowing conversion of 'i' from 'int' to 'double'
sumber