Подтвердить что ты не робот

Что такое int() Called?

Он повторялся снова и снова, что у примитивных типов нет конструкторов. Например, этот _bar не инициализируется 0, когда я вызываю Foo():

class Foo{
    int _bar;
};

Таким образом, очевидно, что int() не является конструктором. Но что это за имя?

В этом примере я бы сказал, что i: (построено? initialized? fooed?)

for(int i{}; i < 13; ++i)

Loki Astari упоминает здесь, что техника имеет свое имя.

EDIT в ответ на Майк Сеймур:

#include <iostream>

using namespace std;

class Foo{
    int _bar;
public:
    void printBar(){ cout << _bar << endl; }
};

int main()
{
    Foo foo;

    foo.printBar();

    Foo().printBar();

    return 0;
}

Запуск этого кода в Visual Studio 2013 дает:

3382592
3382592

Интересно, что gcc 4.8.1 дает:

134514651
0

4b9b3361

Ответ 1

Он повторялся снова и снова, что у примитивных типов нет конструкторов.

Это правильно.

Например, эта строка не инициализируется 0, когда я вызываю Foo()

Да, это так. Foo() указывает инициализацию значения, которая для класса, подобного этому без конструктора, предоставленного пользователем, означает инициализацию нуля перед инициализацией его членов. Итак, _bar заканчивается нулевым значением. (Хотя, как отмечалось в комментариях, один популярный компилятор неправильно инициализирует такие классы.)

Он не будет инициализирован, если вместо этого вы должны использовать инициализацию по умолчанию. Вы не можете сделать это с помощью временного; но объявленная переменная Foo f; или объект new F будут инициализированы по умолчанию. По умолчанию инициализация примитивных типов ничего не делает, оставляя их с неопределенным значением.

Он также не был бы инициализирован, если класс имел предоставленный пользователем конструктор по умолчанию, и этот конструктор специально не инициализировал _bar. Опять же, он будет инициализирован по умолчанию, без эффекта.

Таким образом, int() не является конструктором. Но что это за имя?

В качестве выражения это инициализированное значение типа типа int.

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

В этом примере я бы сказал, что i: (построено? initialized? fooed?)

инициализирован. Список-инициализированный (с пустым списком), инициализированный по значению или нулевой инициализированный, если вы хотите быть более конкретным.

Ответ 2

Здесь, что int() (с учетом того, что грамматически, int является спецификатором простого типа):

[C++11: 5.2.3/1]: Спецификатор простого типа (7.1.6.2) или typename-specifier (14.6), за которым следует заключенный в скобки список выражений, строит значение указанного типа с учетом списка выражений. Если список выражений является одним выражением, выражение преобразования типа эквивалентно (в определенности и, если определено по смыслу), в соответствующее выражение (5.4). Если указанным типом является тип класса, тип класса должен быть полным. Если в списке выражений указано более одного значения, тип должен быть классом с соответствующим образом объявленным конструктором (8.5, 12.1), а выражение T(x1, x2, ...) эквивалентно по сути объявлению T t(x1, x2, ...); для некоторой изобретенной временной переменной t, результатом которой является значение t в качестве значения pr.

Говоря разговорно, он представляет собой создание временного int с пустым инициализатором. Я думаю, что вам удастся найти формальное имя для всей конструкции.

Это не то же самое, что int i{}, которое является полноправным объявлением именованного объекта с инициализатором: ваш i был объявлен, сконструирован и инициализирован.

(Я не думаю, что это связано с тем, что Локи говорил в своем комментарии к этому связанному ответу.)

Ответ 3

Вы можете назвать его псевдоконструктором, если хотите, зеркалирование терминологии для деструктора ( вызовы псевдо-деструктора обсуждаются в С++ 11 §5.2.4). В любом случае int() является значением по умолчанию типа int, то есть 0.

Повторяем утверждение, что "примитивные типы не имеют конструкторов", это довольно глупое и непрактичное представление. С формальной точки зрения примитивные типы не имеют конструкторов, но те, кто цепляются за это утверждение, вовсе не так формальны. Кроме того, с точки зрения машинного кода они этого не делают, но опять же, для тех, кто считает, что утверждение важно, машинный код подобен магии. Однако существует разница, а именно то, что с точки зрения машинного кода общие непримитивные типы POD могут не иметь конструкторов (у них есть конструкторы формально), и я снова сомневаюсь, что те, кто поставил это утверждение вперед, даже знают о проблемы, то есть я не думаю, что они имеют право на мнение. О тех же самых соображениях идет о любом абсолютном терминологическом утверждении: вы можете быть почти уверены, когда вы слышите такое утверждение, что те, кто его делает, почти не знают о том, что связано, и что требование просто непрактично и глупо.

Вместо этого, когда вы слышите, например, "сконструированный" или "вызов конструктора" в контексте примитивных типов, подумайте о том, что это может означать. Формальность - это всего лишь вопрос определения. Важным, за исключением разговоров с адвокатами на языке, где это так или иначе, является наличие концептуальной модели, которая работает.


Все сказанное выше, выражение T() формально не является "конструктором", оно не является конструктором на уровне машинного кода и не является конструктором концептуально в любой осмысленной концептуальной модели.

Это может быть вызов конструктора (действительно, определение конструктора по умолчанию состоит в том, что его можно вызывать на уровне исходного кода без аргументов), но обратите внимание, что нет никакой грамматической категории для вызовы конструктора.

С учетом всего вышеизложенного я бы просто назвал это вызовом конструктора, и когда необходимо уточнить, для примитивного типа T я бы назвал его вызовом псевдоконструктора.


И если кто-то критиковал меня за это, я бы просто бросил им вызов на дуэль.


Обратите внимание, что ваше утверждение о том, что

", он повторялся снова и снова, когда у примитивных типов нет конструкторов. Например, эта строка не инициализируется 0, когда я вызываю Foo()

выражение Foo() выполняет инициализацию значения, так что экземпляр (в этом случае) обнуляется.

Что касается общего отсутствия инициализации локальных автоматических переменных примитивных типов без инициализаторов, то у вас есть такая же ситуация с любым типом без определяемого пользователем конструктора, и даже если используется определенный конструктор, если этот конструктор не инициализирует вещи.

Это иногда приходит как удар для начинающих С++.