GCC が関数宣言を処理する方法に問題があるようです。次の例を見てください。
struct A
{
bool operator () () { return true; }
};
struct B
{
B(bool) { }
};
B b(( // This cannot be parsed as a function declaration,
A()() // and yet GCC 4.7.2 interprets it as such:
)); // "error: 'type name' declared as function returning
// a function B b((A()()));"
int main() { }
の周りに追加の括弧が存在するためA()()
、構文形式B b(( A()() ));
を関数の宣言として解析できません。
質問の例の宣言は少し異なります。
B b(
(A())()
);
ただし、この場合でも、(A())()
を返す関数を返す関数の型として解釈することはできませんA
(常にb
、名前のないパラメーターを持つ関数宣言と見なそうとします)。問題は、他の何かとして解釈できるかどうかです。その場合、およびこのコンテキストで意味がある場合、コンパイラは式全体を object の構築として解析することを検討する必要がありますb
。
これはおそらく、GCC と Clang が意見を異にする基本的な点です。
int main()
{
(A())(); // OK for Clang, ERROR for GCC
}
A
上記が一時的な型を構築し、その呼び出し演算子を呼び出す試み以外のものとしてどのように解釈されるかわかりません。A
が戻り値の型として解釈される場合、名前が欠落しているため (逆も同様) 、関数宣言にすることはできません。
一方、(A())
はタイプ のテンポラリを作成するための有効な式であり、その一時は call 演算子をサポートします (戻り値のタイプはのコンストラクタA
によって受け入れられるタイプと同じです)。B
したがって、(A())()
は type の有効な式である必要がありますbool
。
このような理由から、GCC の構文解析は間違っていると思います。