Pertanyaan Kapan saya harus memilih menyalin elisi melewati argumen dengan referensi const? [duplikat]


Kemungkinan Duplikat:
Apakah pass-by-value merupakan default yang masuk akal dalam C ++ 11? 

saya sedang membaca Ingin Kecepatan? Lewat Nilai. oleh Dave Abrahams tentang copy elision dan RVO. Dan saya bertanya-tanya mengapa kita membutuhkan salinan penghapusan?

Saya telah diberitahu terlalu banyak kali bahwa Anda harus melewati argumen fungsi dengan referensi const untuk menghindari menyalin (hampir setiap buku c ++ saya baca mengatakan kepada saya tentang hal ini).

Misalkan kita memiliki dua fungsi:

int f1(const string &s);
int f2(string s);

Jika argumen aktual adalah rvalue, penyalinan akan dihindari di kedua fungsi. Tetapi jika argumen yang sebenarnya adalah lvalue, menyalin hanya akan dihindari di f1, tidak di f2. Jadi mengapa kita membutuhkan fitur ini?


8
2017-07-07 09:01


asal


Jawaban:


Lewat nilai jika Anda membutuhkan salinannya. Apakah Anda memilih tanda tangan f1 atau tanda tangan f2 tergantung pada isi fungsi. Misalnya, Anda akan menggunakan referensi const dalam kasus ini:

int f1(const string& s) {
    return s.size();
}

Tetapi Anda akan melewati nilai dalam hal ini:

int f2(string s) {
    sort(s.begin(), s.end());
    s.erase(unique(s.begin(), s.end()), s.end());
    return s.size();
}

karena alternatifnya adalah ini:

int f2(const string& s) {
    string temp(s);
    sort(temp.begin(), temp.end());
    temp.erase(unique(temp.begin(), temp.end()), temp.end());
    return temp.size();
}

11
2017-07-07 09:07



RVO tidak berlaku untuk contoh Anda karena nilai kembaliannya int.

string f1(const string &s) {
    string ret = s; // always makes a copy
    ret += 'x';
    return ret; // makes a copy pre-C++11 if no RVO
}

Tally: 1-2 salinan dalam C ++ 03, tepat 1 dalam C ++ 11 plus (jika elision dinonaktifkan) langkah yang dapat berubah menjadi salinan untuk beberapa kelas lain selain std::string.

string f2(string s) { // calling makes a copy if lvalue or no elision
    s += 'x';
    return s; // makes a copy pre-C++11 if no RVO
}

Tally: 0-2 salinan dalam C ++ 03, atau 0-1 dalam C ++ 11.

Seperti yang orang lain katakan, berikan nilai ketika Anda ingin memanipulasi objek sebagai nilai murni, tanpa referensi semantik.

const & adalah ungkapan yang akrab, tapi sedikit kludge dalam hal semantik bahasa. Anda menggunakannya ketika Anda tidak menginginkan referensi sama sekali; itu & hanya berfungsi untuk membuat const berarti dalam definisi parameter. Jika Anda ingin memodifikasi parameter (tetapi hanya secara lokal), lalu const tidak benar-benar berlaku, dan juga & turun juga.


1
2017-07-07 09:08



f2 sinyal dengan tanda tangannya, tidak peduli apa yang Anda berikan kepada saya, saya akan berurusan dengan salinan objek saya sendiri. Berguna, jika f2 akan memodifikasi objek dengan cara yang tidak dapat dibatalkan (misalnya mencuri sumber dayanya dengan bergerak), atau dalam beberapa skenario konkurensi. Diakui, c + + 11 menambah tingkat kebingungan baru ke sistem tipe c ++ yang sudah membingungkan tetapi sekali Anda berpikir tentang itu membuat banyak akal ...


0
2017-07-07 09:14