Rumah >pembangunan bahagian belakang >C++ >Apakah pemajuan sempurna di C dan bagaimana ia berfungsi?
Pemajuan sempurna dalam C adalah teknik yang membolehkan argumen lulus dari satu fungsi ke yang lain sambil mengekalkan kategori nilai asal mereka (LValue atau RValue) dan jenis. Ini amat berguna apabila menulis fungsi templat yang perlu mengemukakan hujah kepada fungsi lain dengan cara yang mengekalkan kecekapan dan semantik panggilan asal.
Kerja pemajuan sempurna dengan menggabungkan rujukan runtuh dan std::forward
. Inilah cara ia beroperasi:
T& &&
) runtuh ke rujukan lvalue ( T&
), dan sebarang kombinasi lain ( T&& &&
atau T& &
) runtuh kepada jenis rujukan paling dalam.T&&
dalam konteks yang disimpulkan (biasanya dengan parameter auto&&
atau Templat).std::forward
digunakan dalam fungsi untuk mengemukakan hujah -hujah ke fungsi lain, memelihara kategori nilai mereka. Apabila anda menggunakan std::forward<t>(arg)</t>
, ia akan membuang arg
ke T
jika T
adalah rujukan lvalue, atau T&&
jika T
adalah rujukan rvalue.Berikut adalah contoh mudah yang menunjukkan penghantaran sempurna:
<code class="cpp">template<typename t> void wrapper(T&amp;& arg) { // Forward 'arg' to another function, preserving its value category anotherFunction(std::forward<t>(arg)); } void anotherFunction(int& arg) { /* lvalue overload */ } void anotherFunction(int&& arg) { /* rvalue overload */ } int main() { int x = 5; wrapper(x); // Calls anotherFunction(int&) because x is an lvalue wrapper(5); // Calls anotherFunction(int&&) because 5 is an rvalue return 0; }</t></typename></code>
Dalam contoh ini, wrapper
menggunakan pemajuan sempurna untuk lulus arg
ke anotherFunction
, yang membolehkan anotherFunction
dibebankan berdasarkan kategori nilai argumen asal.
Manfaat menggunakan pemajuan sempurna di C termasuk:
Pemajuan yang sempurna dapat meningkatkan kecekapan fungsi templat dalam C dalam beberapa cara:
Berikut adalah contoh yang menunjukkan bagaimana pemajuan sempurna dapat meningkatkan kecekapan:
<code class="cpp">template<typename t> void efficientWrapper(T&amp;& arg) { std::vector<int> v(std::forward<t>(arg)); // Efficiently constructs v from arg } int main() { std::vector<int> source = {1, 2, 3}; efficientWrapper(std::move(source)); // Moves the contents of source into v return 0; }</int></t></int></typename></code>
Dalam contoh ini, efficientWrapper
menggunakan pemajuan sempurna untuk membina v
dengan cekap dari arg
. Jika arg
adalah rvalue (seperti dalam fungsi main
), ia menggunakan semantik bergerak untuk mengelakkan penyalinan yang tidak perlu.
Apabila melaksanakan pemajuan sempurna di C, terdapat beberapa perangkap biasa untuk mengetahui dan mengelakkan:
std::forward
: std::forward
hanya boleh digunakan dalam fungsi yang pada asalnya mengambil rujukan penghantaran. Menggunakannya di luar konteks ini boleh membawa kepada tingkah laku yang salah. Sebagai contoh, menyimpan rujukan pemajuan dalam pemboleh ubah ahli dan kemudian menghantarnya kemudian boleh menyebabkan masalah.T&amp; &&
runtuh ke T&
, sementara T&& &&
runtuh ke T&&
.Inilah contoh perangkap yang sama dan bagaimana untuk mengelakkannya:
<code class="cpp">// Incorrect use of std::forward class IncorrectUsage { template<typename t> void incorrectForward(T&amp;& arg) { store = std::forward<t>(arg); // Incorrect: don't use std::forward here } std::string store; }; // Correct use of std::forward class CorrectUsage { template<typename t> void correctForward(T&amp;& arg) { store = std::forward<t>(arg); // Correct: use std::forward immediately } std::string store; };</t></typename></t></typename></code>
Dalam kelas IncorrectUsage
, std::forward
digunakan pada pemboleh ubah anggota yang disimpan, yang boleh membawa kepada tingkah laku yang salah. Dalam kelas CorrectUsage
, std::forward
digunakan dengan serta -merta dalam fungsi, memelihara kategori nilai yang betul dari hujah.
Dengan menyedari perangkap -perangkap ini dan mengikuti amalan terbaik, anda boleh menggunakan pemajuan sempurna untuk menulis kod C yang lebih cekap dan betul.
Atas ialah kandungan terperinci Apakah pemajuan sempurna di C dan bagaimana ia berfungsi?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!