В чем разница между константой x и &xx?
#include
int main() {
const int x = 2;
const int &xx = 3;
cout << x << endl;
cout << xx << endl;
return 0;
}
Зачем нужен &?
Ответ
Семантически эти два объявления различны
const int x = 2;
const int &xx = 2;
В первом случае объявляется константный объект, который инициализируется целочисленным литералом. Для него может даже не выделяться память, если не требуется обращение к памяти объекта. Компилятор может использовать значение этого константного объекта на этапе компиляции. Например,
const int x = 2;
int a[x];
Размер объявленного массива известен на этапе компиляции.
Что касается данного объявления
const int &xx = 2;
то здесь сначала создается временный объект для значения выражения 2, и затем на этот временный объект определяется ссылка. Где разместится в памяти этот временный объект - это будет известно на этапе выполнения программы. Заметьте, что сам временный объект не является константным. Это просто результат вычисления выражения, состоящего из одного операнда - целочисленного литерала 2.
В связи с этим имеется различная реакция компиляторов на использование ссылки xx
Так, например, компилятор MS VC 2016 Community не компилирует следующий фрагмент кода
const int &xx = 2;
int a[xx];
Сообщение об ошибке
Ошибка C2131 выражение не определяется константой 623
Как я думаю, MS VC++ 2016 Community в данном случае ориентируется на следующее положение стандарта C++ о константных выражениях (5.20 Constant expressionю, п. №2)
a non-volatile glvalue of integral or enumeration type that refers to a
complete non-volatile const object with a preceding
initialization, initialized with a constant expression, or
Обратите внимание, что указано, что должна иметь место ссылка на константный объект, в то время как временное выражение, которым инициализируется ссылка вышепоказанного фрагмента кода, является не константным. Поэтому компилятор выдает сообщение об ошибке.
Этот же фрагмент кода успешно компилируется на www.ideone.com . Этот компилятор, по всей видимости, основывается на другом подпункте данного пункта стандарта C++
a non-volatile glvalue of literal type that refers to a non-volatile
object whose lifetime began within the evaluation of e
В этом подпункте ничего не говорится про константность литерального временного объекта. Достаточно, чтобы он имел литеральный тип.
Так что если покопаться в стандарте C++, а также посмотреть на поведение компиляторов, то различия будут явными.:)
Комментариев нет:
Отправить комментарий