Это литье или конструкция?

Я немного смущен, прочитав что-то в учебнике. Что касается кода:

void doSomeWork(const Widget& w)
{
    //Fun stuff.
}

doSomeWork(Widget(15));

doSomeWork() принимает параметр const Widget&. В учебнике Effective С++ III указано, что это создает временный объект Widget для перехода к doSomeWork. В нем говорится, что это можно заменить на:

doSomeWork(static_cast<Widget>(15));

так как обе версии являются отличными - первый - это просто строчный C-образный стиль. Я бы подумал, что Widget(15) будет ссылаться на конструктор для виджета, который принимает один целочисленный параметр.

Будет ли выполняться конструктор в этом случае?

Ответ 1

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

Даже когда вы создаете временное использование конструктора с несколькими аргументами (как в Widget(1, 2, 3)), он по-прежнему считается вариацией функциональной нотации (см. 5.2.3)

Другими словами, ваш вопрос "Является ли это литой или конструкцией" неправильно сформулирован, поскольку он подразумевает взаимную эксклюзивность между листами и "конструкциями". Они не являются взаимоисключающими. Фактически, преобразование каждого типа (будь то явное приведение или что-то более неявное) - это не что иное, как создание ( "строительство" ) нового временного объекта целевого типа (исключая, возможно, некоторые инициализации ссылок).

BTW, функциональная нотация - это в основном обозначение С++. Язык C не имеет функциональных стилей.

Ответ 2

Короткие: Да.

Long

Вы всегда можете проверить эти вещи самостоятельно, например:

#include <iostream>

struct W
{
    W( int i )
    {
        std::cout << "W(" << i << ")\n";
    }
};

int main(int argc, const char *argv[])
{
    W w(1);
    W(2);
    static_cast<W>(3);
}

который выводит

W(1)
W(2)
W(3)

Ответ 3

Да, это и то, и другое:). Литой является синтаксическая конструкция (т.е. Что-то, что вы вводите). В этом случае конструктор вызывается в результате приведения. Как конструктор будет вызван в результате ввода

Widget w(15);

Ответ 4

Оба Widget(15) и static_cast<Widget>(15) - это отбрасывание или преобразование операторы, если хотите. Оба создают новый объект назначенного типа, преобразуя 15 в Widget. Поскольку 15 не имеет операторов преобразования, единственный способ сделать это преобразование - выделение необходимой памяти (в стеке) и вызов соответствующий конструктор. Это действительно не так, что double(15) и static_cast<double>(15), за исключением того, что мы обычно не думаем о double как имеющий конструктор (но полученный double является новым объект, отличный от 15, который имеет тип int).

Ответ 5

Ты сказал:

первый - это просто функциональный стиль C, который, по-видимому,

Первый не будет компилировать в C, это не C-стиль. Стиль C выглядит как (Widget)15. Здесь создается временный объект, используя Widget::Widget(int).

Следовательно, это не C-стиль.

Ответ 6

Да, конечно. Любой конструктор принимает один параметр, который будет рассматриваться как CONVERSION CONSTRUCTOR. Ваш конструктор уже принимает один параметр int, так что компилятор может "неявно" вызвать этот конструктор для соответствия аргументу (со значением 15, который равен int).

Существует простой способ предотвратить такие ошибки, просто используйте ключевое слово explicit перед вашим конструктором.

Подробнее о .

Ответ 7

Yeeeah. Вы можете заменить

Widget(15)

с

static_cast<Widget>(15)

Потому что он будет заменен обратно компилятором: D

Когда вы бросаете int в Widget, компилятор ищет Widget::Widget(int); и помещает его там.