C++ rvalue временные файлы в шаблоне

Можете Вы объяснять меня различие между механизмом следующего:

int function();

template<class T>
void function2(T&);

void main() {
    function2(function()); // compiler error, instantiated as int &

    const int& v = function();
    function2(v); // okay, instantiated as const int&
}

мое обоснование корректно относительно инстанцирования? почему сначала не инстанцирован как const T&?

Спасибо

8
задан Anycorn 8 June 2010 в 05:35
поделиться

4 ответа

Поскольку функция возвращает неконстантное значение. Только объекты могут быть константными, потому что они хранят некоторое состояние, которое можно было бы изменить, если бы оно не было константой. То, что вы там возвращаете, - это не объект, а чистая ценность. Концептуально их нельзя изменить (например, константы перечисления), но они не квалифицируются как константы (как, опять же, константы перечисления).

3
ответ дан 5 December 2019 в 23:13
поделиться

В этой строке

function2(function()); 

после возврата функции2, аргумент, который передается ей, может иметь измененное значение, но так как функция() возвращается и она просто присваивается временной переменной, но что произойдет с этой временной переменной после того, как она выйдет из области видимости - это проблема, поэтому компилятор жалуется.

0
ответ дан 5 December 2019 в 23:13
поделиться

Для компиляции первого вызова необходимо определить функцию 2 с параметром T && - это rvalue, ссылка на временный объект. Во втором вызове v - ссылка на lvalue, все в порядке. Если ваш компилятор не поддерживает ссылки rvalue, первый вызов может быть скомпилирован только с параметром T без ссылки.

0
ответ дан 5 December 2019 в 23:13
поделиться

Я думаю, вы могли запутаться между rvalue и квалификатором const. Функция возвращает неконстантное временное rvalue типа int, поэтому компилятор выводит T как int, как и должно быть. Как вы указываете, вы можете привязать временное значение к const ref (c ++ 03 12.2 / 5), но компилятор не будет добавлять квалификаторы cv, чтобы сделать вызов функции правильно сформированным. Поскольку вы не можете управлять функцией шаблона, есть два способа обойти это (в дополнение к решению, которое вы опубликовали).

(1) Явные параметры шаблона: function2 (function ())

(2) cv qualify return: const int function ();

Оба эти решения являются хорошо сформированный. (1) кажется лучшим решением, ИМХО, поскольку (2) нетрадиционно и глупо.

Редактировать: Фактически, выведенный тип может быть более квалифицированным cv, чем аргумент для аргумента шаблона ссылки, но только если в противном случае выведение типа завершилось бы ошибкой (c ++ 03 14.8.2.1/3). В этом случае определение типа не завершается ошибкой, но приводит к неправильному вызову функции (SFINAE не применяется, поскольку сама специализация функции шаблона не искажена).

Если намерение автора шаблона состояло в том, чтобы не изменять аргумент, он должен быть объявлен как аргумент ссылки на константу, так что это может быть ошибка в библиотеке шаблонов, или он может изменить аргумент, и в этом случае вы are done завершится ошибкой, если функция попытается изменить аргумент.

Редактировать: Как указывает FredOverflow, неклассовые значения r всегда являются cv неквалифицированными по стандарту 3.10 / 9. Итак, (2), который работает под gcc 4.3, на самом деле является ошибкой компилятора (gcc <4.5, согласно FredOverflow).

2
ответ дан 5 December 2019 в 23:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: