Pertanyaan Mengapa C ++ dapat mendeduksi argumen template di sisi kanan operator penugasan dari sisi kiri?


template <typename T>
void func(T&){
}

int main(){
    void (*p)(int&) = func;//or &func
    return 0;
}

Saya bertanya-tanya mengapa kode ini dikompilasi (dengan g ++). Tampaknya argumen fungsi template disimpulkan dari tipe p? Apakah ini perilaku standar?

Edit: Saya datang dengan penjelasan yang mungkin. Tugas itu memiliki tanda tangan:

void(*&)(int&)operator=(void(*)(int&));

Jadi func sebenarnya dideduksi dari jenis argumen input dari operator =, bukan dari jenis p langsung. Apakah itu benar?


32
2017-12-22 10:03


asal


Jawaban:


Apakah ini perilaku standar?

Ya itu. Pengurangan argumen template juga terjadi ketika Anda mengambil alamat dari template fungsi (seperti yang Anda lakukan saat menugaskan atau menginisialisasi penunjuk fungsi). Ini secara eksplisit diizinkan masuk [temp.deduct.funcaddr] / 1:

Argumen kerangka dapat disimpulkan dari jenis yang ditentukan saat mengambil   alamat fungsi yang kelebihan beban. Template fungsi   jenis fungsi dan jenis yang ditentukan digunakan sebagai jenis P dan A,   dan deduksi dilakukan seperti yang dijelaskan di [temp.deduct.type].

Jenis penunjuk fungsi menyediakan argumen (A di paragraf di atas).

Jadi func sebenarnya dideduksi dari tipe argumen input dari operator =, bukan dari tipe p secara langsung. Apakah itu benar?

Tidak juga. Untuk satu, itu bukan tugas, itu inisialisasi yang Anda lakukan. Dan bahkan jika itu menggunakan kelebihan beban operator= berfungsi, Anda perlu deduksi untuk menginisialisasi argumen operator penugasan, yang membawa Anda kembali ke titik awal.


29
2017-12-22 10:07