Apakah boleh mengembalikan nilai argumen default dengan referensi const seperti pada contoh di bawah ini:
https://coliru.stacked-crooked.com/a/ff76e060a007723b
#include <string>
const std::string& foo(const std::string& s = std::string(""))
{
return s;
}
int main()
{
const std::string& s1 = foo();
std::string s2 = foo();
const std::string& s3 = foo("s");
std::string s4 = foo("s");
}
c++
language-lawyer
object-lifetime
default-arguments
reference-binding
Hati yang beku
sumber
sumber
std::string
dengan kelas Anda sendiri sehingga Anda dapat melacak konstruksi dan penghancuran.Jawaban:
Dalam kode Anda, keduanya
s1
dans3
menggantung referensi.s2
dans4
baiklah.Dalam panggilan pertama,
std::string
objek kosong sementara yang dibuat dari argumen default akan dibuat dalam konteks ekspresi yang berisi panggilan. Oleh karena itu, ia akan mati pada akhir definisis1
, yang meninggalkans1
menggantung.Dalam panggilan kedua,
std::string
objek sementara digunakan untuk menginisialisasis2
, lalu mati.Dalam panggilan ketiga, string literal
"s"
digunakan untuk membuatstd::string
objek sementara dan yang juga mati pada akhir definisis3
, meninggalkans3
menggantung.Dalam panggilan keempat,
std::string
objek sementara dengan nilai"s"
digunakan untuk menginisialisasis4
dan kemudian mati.Lihat C ++ 17 [class.t Sementara] /6.1
sumber
Itu tidak aman :
sumber
std::string s2 = foo();
valid (toh, tidak ada referensi yang diteruskan secara eksplisit)?Itu tergantung pada apa yang Anda lakukan dengan string sesudahnya.
Jika pertanyaan Anda apakah kode saya benar? maka ya itu.
Dari [dcl.fct.default] / 2
Jadi kode Anda secara efektif setara dengan:
Semua kode Anda benar, tetapi tidak ada ekstensi seumur hidup referensi dalam semua kasus ini, karena jenis pengembalian adalah referensi.
Karena Anda memanggil fungsi dengan sementara, masa string yang dikembalikan tidak akan memperpanjang pernyataan.
Contoh Anda dengan
s2
tidak apa-apa karena Anda menyalin (atau memindahkan) dari sementara sebelum akhir satement.s3
memiliki masalah yang sama dengans1
.sumber