@thisnotes
Прислал мне просто восхитительную вещь.
Давайте посмотрим вот на этот код
const std::vector<Obj>& vec =
(argc > 1)
? std::vector<Obj>{}
: ready_vec;
Вот тут зашита просто удивительая проблема. Нет, это не ссылка на временный объект, потому что
const продлевает время жизни ссылки. Интересный факт, что вот такой код
#include <iostream>
#include <vector>
struct Obj {
explicit Obj() {}
Obj(const Obj&) {
std::cout << "copy\n";
}
};
int main(int argc) {
auto ready_vec = std::vector<Obj>{};
ready_vec.reserve(1);
ready_vec.emplace_back();
const std::vector<Obj>& vec =
(argc > 1)
? std::vector<Obj>{}
: ready_vec;
return vec.size();
}
Компилируется в 16 строк ассемблера, а вот если мы сделаем вот так:
#include <iostream>
#include <vector>
struct Obj {
explicit Obj() {}
Obj(const Obj&) {
std::cout << "copy\n";
}
};
int main(int argc) {
auto ready_vec = std::vector<Obj>{};
ready_vec.reserve(1);
ready_vec.emplace_back();
const auto empty_vec = std::vector<Obj>{};
const std::vector<Obj>& vec =
(argc > 1)
? empty_vec
: ready_vec;
return vec.size();
}
Компилируется в 6 строк ассемблерного кода.
А фокус в том, что тернарный оператор в этой строчке
const std::vector<Obj>& vec =
(argc > 1)
? std::vector<Obj>{}
: ready_vec;
должен оба аргумента конвертировать к одному типу. А временный объект к ссылке сконвертировать не получится, поэтому и второй аргумент к ссылке не может быть конвертирован, и создается временная копия вектора.
Думаю, в комментариях он подскажет, был ли этот пример найден в продуктовой задаче...