Здесь вы правильно озадачен, потому что есть два независимых странные факты смешивания в:
- Ваш компилятор позволяет неконстантная ссылка на обязательность временного. Это исторически было ошибкой в компиляторах Microsoft и не разрешено стандартом. Этот код не должен компилироваться.
- Стандарт, однако, как ни странно, на самом деле позволяет привязывать
const
ссылки на временные рамки и имеет специальное правило для этого: временный объект не будет немедленно уничтожен (как это было бы нормально), но его жизнь будет продлена до срока службы ссылка.
В коде:
std::vector<int> foo() {
std::vector<int> x{1,2,3};
return x;
}
int main() {
const std::vector<int>& x = foo(); // legal
for (auto& item : x) {
std::cout << x << std::endl;
}
}
Причина этого, по-видимому абсурдной правило о связывании константных ссылок на временный является то, что в C++ есть очень общий «шаблон» (1) прохождения константных ссылок вместо значения для параметров, даже если личность не имеет значения. Если объединить это (анти) -pattern с неявным преобразованием, что происходит, является то, что, например:
void foo(const std::string& x) { ... }
не будет вызываемым с
foo("Hey, you");
без специального правила, потому что const char *
(дословный) неявно преобразовывается во временный std::string
и передается как параметр, связанный с ссылкой на константу.
(1) Образец действительно очень плохой с философской точки зрения, потому что значение является значением, а ссылка является ссылкой: эти два являются логически отличными понятиями. A const reference is not a value and confusing the two can be the source of very subtle bugs. C++, однако, одержим по производительности и, особенно перед семантикой переноса, передавая ссылки на const, считается «умным» способом передачи значений, несмотря на то, что это проблема из-за проблем с продолжительностью жизни и псевдонимов и для усложнения оптимизатора. С современным компилятором передача ссылки должна использоваться только для «больших» объектов, особенно тех, которые не, построенных на лету, которые нужно передать, или когда вас действительно интересует идентификация объекта, а не только значение объекта.
Скомпилирует? Если это вы используете MSVS? – NathanOliver
Да, его Visual Studio 2005 – Kobe
ОК. Обратите внимание, что это нестандартный код. MSVS позволяет это, но это не будет работать на большинстве других компиляторов. – NathanOliver