Как С++ обрабатывает константу double и которая ссылается на int?
Я работал над некоторым шаблоном кода сегодня утром, когда использовал BOOST_STATIC_ASSERT
, чтобы убедиться, что я не создавал ссылку на неправильный тип, поскольку я думал, что это может быть более ясное сообщение об ошибке. Однако, когда я попытался удалить статический assert, чтобы взглянуть на альтернативную ошибку компилятора, я был потрясен, обнаружив, что gcc даже не жалуется, когда вы пытаетесь создать const double & ссылаясь на int:
#include <iostream>
int main()
{
int x = 5;
const double& y = x;
std::cout << y << std::endl;
return 0;
}
Скомпилирует и даже не предупреждает:
$ g++ ~/stuff/badRef.cpp -Wall -Wextra -pedantic
$ a.out
5
Что здесь происходит? Это поведение undefined? Если да, то почему GCC не жалуется? На моей машине int составляет 4 байта, а double - 8. Это означает, что при печати double & он должен интерпретировать 8 байтов на этом адресе как двойной и распечатать его, но в этом месте на самом деле есть 4 байта int.
Очень смутно. Помогите!
Ответы
Ответ 1
const double& y = x;
создает временный double
со значением static_cast<double>(x)
, а затем привязывает это временное значение к y
. Время жизни временного расширения увеличивается до времени жизни y
.
Это полностью законный С++ (03 и 11), следовательно, отсутствие предупреждения/ошибки.
Ответ 2
он четко определен и легален. y
относится к временному. рассмотрите также, когда вы передаете параметры:
void foo(const int& p);
foo(3.14);
Обратите также внимание, что это недопустимо С++, если ссылка не const. VS 6 получил это неправильно и разрешил привязывать переменную ссылку на временную. Это относится только к ссылкам const.
Ответ 3
const T&
может привязываться к временному, поэтому x
преобразуется в double
, а копия привязана к y
. Если вы проверите, вы увидите, что &x != &y
. Причиной такого поведения является возможность передачи литералов функциям, которые принимают свои параметры по ссылке const
.
Ответ 4
Это хороший пример для тех, кто считает, что указатели и ссылки одинаковы.
double const*const y2 = &x;
gives
bad.cpp:7:30: error: cannot convert ‘int*’ to ‘const double* const’ in initialization
Причина, по которой он работает для ссылок, объясняется в других сообщениях.