С++ spooky конструктор

Возможный дубликат:
Почему это ошибка при использовании пустого набора скобок для вызова конструктора без аргументов?

Позволяет иметь этот код

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?

Ответ 1

Foo f3(); объявляет функцию с именем f3 с возвращаемым типом Foo.

Ответ 2

Третья строка анализируется как объявление функции, которая не принимает аргумента и возвращает Foo.

Ответ 3

С++ имеет правило, что если оператор можно интерпретировать как объявление функции, он интерпретируется таким образом.

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

Ответ 4

  • f1 вызывает конструктор копирования после явного вызова, вы ошибались на этом
  • f2 - явный вызов конструктора//вы тоже были неправы.
  • f3 объявляет функцию
  • f4 снова является конструктором копирования, например f1//вы здесь.
  • f5 вызовет конструктор по умолчанию//вы снова здесь.

Ответ 5

Это не то, что вы думаете:

 Foo f3();

Вы можете подумать, что это явный вызов конструктора по умолчанию, но это не так. Это фактически объявление функции с именем f3, которая не принимает параметров и возвращает значение Foo по значению.

То, что это анализируется как объявление функции, а не вызов конструктора, называется Most Vexing Parse.

Ответ 6

Вы определили функцию f3, которая возвращает foo в случае 3. В случае 5 у вас нет конструктора по умолчанию, поэтому вы получаете ошибку.