Это литье или конструкция?
Я немного смущен, прочитав что-то в учебнике. Что касается кода:
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);
и помещает его там.