Вопрос

Не могли бы вы, пожалуйста, объяснить мне разницу между механизмом следующего:

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&?

Спасибо

Это было полезно?

Решение

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

Другие советы

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

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

(2) возврат резюме, отвечающего требованиям: const int function();

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

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

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

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

В этой линии

function2(function()); 

После возврата Function2 аргумент, который переходит к нему Почему компилятор жалобы.

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top