Ответ 1
Foo f3();
объявляет функцию с именем f3
с возвращаемым типом Foo
.
Возможный дубликат:
Почему это ошибка при использовании пустого набора скобок для вызова конструктора без аргументов?
Позволяет иметь этот код
class Foo {
Foo(int) { }
};
Тогда мы имеем результаты:
int main() {
Foo f1 = Foo(5); // 1: OK, explicit call
Foo f2(5); // 2: OK, implicit call
Foo f3(); // 3: no error, "f3 is a non-class type Foo()", how so?
Foo f4(f1); // 4: OK, implicit call to default copy constructor
Foo f5; // 5: expected error: empty constructor missing
}
Можете ли вы объяснить, что происходит в случае 3?
Foo f3();
объявляет функцию с именем f3
с возвращаемым типом Foo
.
Третья строка анализируется как объявление функции, которая не принимает аргумента и возвращает Foo
.
С++ имеет правило, что если оператор можно интерпретировать как объявление функции, он интерпретируется таким образом.
Следовательно, синтаксис Foo f3();
фактически объявляет функцию, которая не принимает аргументов и возвращает Foo
. Поработайте с этим, написав Foo f3;
, он также вызовет конструктор по умолчанию (если он есть, конечно).
f1
вызывает конструктор копирования после явного вызова, вы ошибались на этомf2
- явный вызов конструктора//вы тоже были неправы.f3
объявляет функциюf4
снова является конструктором копирования, например f1
//вы здесь.f5
вызовет конструктор по умолчанию//вы снова здесь.Это не то, что вы думаете:
Foo f3();
Вы можете подумать, что это явный вызов конструктора по умолчанию, но это не так. Это фактически объявление функции с именем f3
, которая не принимает параметров и возвращает значение Foo
по значению.
То, что это анализируется как объявление функции, а не вызов конструктора, называется Most Vexing Parse.
Вы определили функцию f3, которая возвращает foo в случае 3. В случае 5 у вас нет конструктора по умолчанию, поэтому вы получаете ошибку.