С++ самый неприятный синтаксический анализ снова

Взято непосредственно из http://herbsutter.com/2013/05/09/gotw-1-solution/

Пока widget w(); понятен для меня, я понятия не имею, как нижний код может быть объявлением функции?

// same problem (gadget and doodad are types)
//
widget w( gadget(), doodad() );  // pitfall: not a variable declaration

Как это возможно?

Ответ 1

В объявлении функции аргументы массива типов распаковываются в указатели на первый элемент, аргументы функции типа распадаются на указатель функции, поэтому сигнатура будет:

widget w( gadget(*)(), doodad(*)() );

То есть, функция, которая принимает в качестве первого аргумента указатель на функцию, не принимающую аргументов и возвращающую gadget, которая принимает в качестве второго аргумента указатель на функцию, не принимающую аргументов и возвращающую doodad, и что сама функция возвращает a widget

Есть еще более интересные или запутанные случаи, например:

// assume 'x' is a variable defined somewhere:
widget w(gadget(x));

Как это можно интерпретировать как объявление функции? Я имею в виду, x - переменная, не так ли? Ну, при объявлении переменной вы можете добавить дополнительные скобки, поэтому gadget x; и gadget (x); объявляют одну и ту же переменную x. То же самое относится к аргументам функций, поэтому приведенный выше код выглядит как объявление функции, которая принимает первый аргумент с именем x типа gadget и возвращает widget...

Ответ 2

Эта функция получает две функции, которая возвращает gadget и doodad, и ни один из них не получает никаких аргументов.

Пример, который компилируется отлично.

#include <iostream>
class widget{};
class gadget{};
class doodad{};
gadget a(){}
doodad b() {};
widget w( gadget(), doodad() ){
}
int main() {
    w(a,b);
    return 0;
}

http://ideone.com/YjZK9Y