На точке 1. Предполагая, что виджет является структурой или классом,
f = processWidget(Widget());
Для того чтобы работы, processWidget должны быть объявлены что-то вроде:
int processWidget(const & Widget);
Хотя это может быть немного усложнено тем факт, что могут быть классы, полученные из Widget, которые могут автоматически конвертироваться в виджет или в другие контексты, в которых такое преобразование предоставляется, давайте просто рассмотрим эту базовую форму. Widget()
собирается создать виджет «на месте». В других контекстах мы могли бы написать
Widget w();
что в точности то же самое, только теперь созданный виджет имеет имя (ш). Widget() собирается создать временное, которое будет уничтожено сразу же после завершения инструкции, в которой она отображается. Таким образом, этот временный виджет предоставляется как const & Widget
функции processWidget
. Это будет продолжаться до тех пор, пока эта функция будет выполняться. Когда эта функция вернется, она предоставит возвращаемое значение f, после чего временный виджет будет уничтожен (будет вызываться функция деструктора).
Заметим также, что вы можете сделать:
Widget w;
w = Widget();
Это странное использование создает временный виджет, который копируется в ш. Причина, по которой это применимо к вашему вопросу о processWidget(Widget())
, состоит в том, что =
в этом контексте является оператором. Это может быть перегруженная операторская функция, написанная для предоставления некоторой уникальной операции копирования, но даже автоматически сгенерированная версия принимает параметр, const & Widget
, о котором я упоминал для параметра в объявлении processWidget. Это означает, что в принципе это одно и то же.
В этой связи int()
делает что-то подобное, но эта точная форма создавала бы int uninitialized в некоторых компиляторах, что не очень хорошо (в современном C++ оно было бы нулевой инициализировано).
Однако, если виджет() является функцией возвращает значение, объявленный как:
int Widget();
Затем processWidget
должен был бы быть объявлена таким образом, чтобы принять целое число, или тип, который преобразует на целое число, чтобы вызов работал.
В точке 2:
Widget()
только будет «видеть» как тип функции, если есть объявление функции. Если Widget является структурой или классом, компилятор определяет это путем поиска. Когда компилятор пытается понять, что имеется в виду при использовании Widget
, за которым следует распознаваемый оператор функции ()
, он тогда «видит», было объявление для функции этого имени, которое затем дает ему знание возвращаемого типа, параметры объявлен и т.д.Другими словами, Widget()
как выражение не имеет изолированного значения для C++, не являющегося ключевым словом или другим распознаваемым объявлением, и ему предоставляется контекст, из которого значение выводится на основе предоставленного объявления. Если Widget объявлен как структура, компилятор не будет «знать» Widget как объявление функции, но может понимать, что он является структурой, для которой был предоставлен (или будет предоставлен) автоматический конструктор по умолчанию или для которого была дана соответствующая декларация соответствия.
Как указать 3.
Конструкторы понимается уникальная категория функций C++. Любой конструктор, принимающий единственный аргумент, подразумевает, что предоставленный параметр является способом построения объекта из других заданных типов. В вашем вопросе комментарий, который вы предоставили с
Widget("convert string to widget") // a form of explicit cast
Предлагает это отливка, но это не так. Это конверсия. Это огромная разница. Приведение не создает новый объект, но выполняется преобразование.
Предполагается, что конструкторы, принимающие один параметр, являются объявлениями конверсии, они указывают, как создать виджет, заданный другим типом. Если виджет может быть изготовлен из const char *
, как вы намекнули, это означает, что один конструктор в классе виджета объявить:
Widget(const char *);
Это означает, что вы можете сделать виджет из строкового литерала, или что-то который преобразуется в строковый литерал (const char *). В контексте, где виджет может потребоваться в качестве параметра, он сообщает компилятору, что он может его построить, если предоставляется const char *
. Это полная противоположность операторам преобразования, где они возвращают представление Widget, как если бы это был какой-то другой тип. Если, например, вы можете представлять Widget как std :: string, вы можете предоставить оператор преобразования для одного (хотя такие операторы могут быть сложными). Довольно типичное использование заключается в предоставлении оператора преобразования для bool. Это не означает, что Widget может представлять собой как bool, но если тип виджета использовался в контексте Bool, скажем, if (!w)
, где w имеет вид Widget, то этот виджетов ACTS, как bool в этот момент, возможно что виджет не подходит, и что-то нужно сделать.
Это все тот же случай. Выражение 'Type (stuff)' означает: создать объект типа 'Type' с инициализатором' stuff'. –