Sejak C++17 (lebih tepatnya, sejak p0135r1 ), konversi array-ke-pointer melibatkan materialisasi sementara - conv.array:

Nilai atau nilai dari tipe “array of N T” atau “array of unknown bound of T” dapat dikonversi menjadi nilai awal dari tipe “pointer to T”. Konversi materialisasi sementara ([conv.rval]) diterapkan. Hasilnya adalah pointer ke elemen pertama dari array.

Mengapa? Perwujudan sementara hanya berlaku untuk nilai-nilai - conv.rval:

Nilai awal tipe T dapat dikonversi ke nilai x tipe T. Konversi ini menginisialisasi objek sementara ([kelas.temporer]) tipe T dari nilai awal dengan mengevaluasi nilai awal dengan objek sementara sebagai objek hasil, dan menghasilkan xvalue yang menunjukkan objek sementara. T harus tipe lengkap.

Jadi, dalam hal konversi array-ke-pointer, untuk apa materialisasi sementara diterapkan? Untuk nilai pointer yang dihasilkan?

Apakah materialisasi sementara terjadi pada contoh berikut?

void foo(int *a) {}
int main() {
    int arr[4];
    foo(arr);
}
7
Jan Tušil 7 Agustus 2019, 13:19

1 menjawab

Jawaban Terbaik

Konversi materialisasi sementara diterapkan ke array yang akan dikonversi jika itu adalah nilai awal. Ini karena pointer hanya bisa menunjuk ke sesuatu yang benar-benar ada. Itu tidak diterapkan pada nilai pointer yang dihasilkan. Dalam contoh Anda, larik yang akan dikonversi adalah nilai, jadi konversi tidak diterapkan.

Dalam kode berikut, nilai array Arr{0, 1} diubah menjadi int*. Konversi materialisasi sementara diterapkan.

void f(int*) {}
int main()
{
    using Arr = int [2];
    f(Arr{0, 1});
}

GCC tampaknya tidak menerima kode ini, tetapi tidak ada masalah dengan kode ini sesuai standar. Lihat Mengapa meneruskan objek sementara sebagai argumen memerlukan std::move?

2
L. F. 9 Agustus 2019, 13:46