Definisi common_type yang dipertanyakan

dalam buku "Perpustakaan standar Cpp", edisi ke-2, oleh Nicolai M. Josuttis, mengatakan (5.4, p.125) bahwa definisi tipe umum struct adalah sebagai berikut:

template <typename T1, typename T2>
struct common_type<T1,T2> {
typedef decltype(true ? declval<T1>() : declval<T2>()) type;
};

Saya memiliki masalah serius untuk mempercayai bahwa ini adalah definisi common_type yang benar. Alasan:

typedef decltype(true ? declval<T1>() : declval<T2>()) type;//As far as I understand this will always pick second operand, declval<T1>(), due to the fact that there is 'true' value. Am I right?

person smallB    schedule 07.11.2012    source sumber
comment
Ekspresinya sebenarnya tidak dievaluasi, ia hanya mengambil tipenya saja.   -  person Some programmer dude    schedule 07.11.2012
comment
@JoachimPileborg ya, saya memahaminya, tetapi ternary ?: akan selalu mengembalikan operan di sisi kiri ':' jika nilainya di depan '?' adalah benar.   -  person smallB    schedule 07.11.2012
comment
Kalau mungkin juga false, karena kodenya tidak pernah dijalankan. Kemungkinan besar tidak pernah ada kode apa pun yang dibuat untuk ini. Bahkan merupakan kesalahan jika ada std::declval dalam kode yang dieksekusi.   -  person Some programmer dude    schedule 07.11.2012
comment
Ingatlah bahwa meskipun ini akan dievaluasi (padahal sebenarnya tidak), ekspresi operator ternary tidak secara otomatis memiliki tipe operan yang dikembalikan, karena itu hanya diketahui pada saat runtime (bahkan jika dalam kasus ini kondisinya adalah konstanta waktu kompilasi, tapi itu hanya kasus khusus). Jadi itu harus berupa tipe umum dari kedua operan, agar tipenya diketahui pada waktu kompilasi.   -  person Christian Rau    schedule 07.11.2012
comment
Detail: Definisi common_type ini mengakibatkan perilaku yang tidak diinginkan dalam beberapa kasus, lihat laporan kerusakan DR2142. Namun jawaban Eugene Mamin masih benar.   -  person dyp    schedule 08.11.2012


Jawaban (1)


Ini semua tentang operator bersyarat. Ini bukan pernyataan pilihan seperti if atau switch.

5.16 paragraf standar ISO C++11:

Sebaliknya, jika operan kedua dan ketiga memiliki tipe yang berbeda dan memiliki tipe kelas (mungkin berkualifikasi cv), atau jika keduanya merupakan nilai gl dengan kategori nilai dan tipe yang sama kecuali untuk kualifikasi cv, upaya dilakukan untuk mengonversi masing-masing operan tersebut. dari operan tersebut ke tipe operan lainnya.

Jadi, tidak masalah jika decltype berisi kondisi yang benar, kompiler harus memilih tipe yang umum sebagai hasilnya.

UPD: 5.16 berisi penjelasan lebih lanjut tentang perilaku yang benar, Anda harus melihatnya untuk memahami keseluruhan proses secara menyeluruh. Namun untuk pertanyaan khusus Anda:

Dengan menggunakan proses ini, ditentukan apakah operan kedua dapat dikonversi agar cocok dengan operan ketiga, dan apakah operan ketiga dapat dikonversi agar cocok dengan operan kedua. Jika keduanya dapat dikonversi, atau salah satu dapat dikonversi tetapi konversinya tidak jelas, maka program tersebut tidak tepat sasaran. Jika tidak ada yang dapat dikonversi, operan tidak diubah dan pemeriksaan lebih lanjut dilakukan seperti dijelaskan di bawah. Jika tepat satu konversi dimungkinkan, konversi tersebut diterapkan ke operan yang dipilih dan operan yang dikonversi digunakan sebagai pengganti operan asli untuk sisa bagian ini.

person Eugene Mamin    schedule 07.11.2012
comment
Hai, terima kasih atas jawaban Anda, satu-satunya masalah yang saya miliki adalah: ada upaya untuk mengubah masing-masing operan tersebut ke tipe yang lain. Bagaimana cara kerjanya? Apakah compiler mengubah tipe operan kiri ke tipe kanan atau sebaliknya? Apakah ada aturan untuk itu? - person smallB; 07.11.2012