Почему данная строка не вызывает у разработчиков стандарта казуса?
auto p = new auto(42);
Ответы
Ответ 1
Есть четыре вида длительности хранения памяти под объект (storage duration), и соответственно четыре способа создать объект:
статическая, static T variable(expression),
потока, thread_local T variable(expression),
автоматическая, T variable(expression),
динамическая, new T(expression).
Было бы странно, если бы вывод типов работал бы только для первых трех способов
но не работал бы для динамически выделяемой памяти.
Ответ 2
Когда используется спецификатор типа auto, то реальный тип выводится на основе типа инициализатора.
В этом выражении
new auto(42)
тип создаваемого динамически объекта определяется, исходя из типа выражения, используемого в качестве инициализатора объекта.
В данном случае это целочисленный литерал 42 , имеющий тип int. Поэтому создается объект этого типа в динамической памяти и инициализируется значением 42.
Сам оператор возвращает указатель на созданный объект, то есть в приложении к данному примеру возвращается указатель int *
Поэтому в исходном предложении
auto p = new auto(42);
тип переменной p в свою очередь определяется из типа инициализатора в правой части от знака =, который, как я указал выше, имеет тип int *.
То есть в этом предложении создается два объекта, один - это безымянный объект
динамической памяти, а второй - это указатель, возможно, в автоматической или статической области памяти, и тип каждого из этих объектов определяется на основе соответствующего типа выражения, используемого в качестве инициализатора.
Вообще-то не следует злоупотреблять спецификатором auto, так как порой это може
вызывать затруднения у читающего код, чтобы определить, какой реальный тип компилятор выведет для переменной со спецификатором auto.
Рассмотрите следующий, казалось бы, очень простой пример,
unsigned int x = 0;
long y = 0;
auto p = new auto( x + y );
Не каждый сможет правильно ответить, какой будет тип у указателя p, так как помимо всего прочего, правильный ответ зависит в том числе от используемой платформы.
Вот вам еще в копилку подобная на первый взгляд странная конструкция на этот ра
касающаяся оператора преобразования, о которой можете почитать здесь
Сейчас в стандарте C++ появилось много конструкций, которые интуитивно непонятны.
Я приведу пример одной из таких конструкций
int a[] = { 1, 2, 3 };
decltype( auto ) c = ( a );
Обратите внимание на объявление переменной c и заключение в круглые скобки выражения ( a ). Оказывается, это не совсем одно и то же, что объявление
int a[] = { 1, 2, 3 };
decltype( auto ) c = a;
где выражение a не заключено в круглые скобки. Это предложение не будет компилироваться
в то время как предыдущее предложение с инициализатором в круглых скобках успешно скомпилируется.:)
Ответ 3
Это тоже самое, что int* i = new int(42);
Комментариев нет:
Отправить комментарий