g ++ lehnt ab, clang ++ akzeptiert: foo (x) ("bar") ("baz");

Jemand hattefragt neulich wieso kompiliert sowas mit clang, aber nicht mit gcc. Ich verstand intuitiv, was passierte, und konnte der Person helfen, aber ich fragte mich, welcher Compiler laut Norm richtig war. Hier ist eine abgespeckte Version des Codes:

#include <iostream>
#include <string>

class foo
{
public:
    foo(const std::string& x):
        name(x)
    { }
    foo& operator()(const std::string& x)
    {
        std::cout << name << ": " << x << std::endl;
        return (*this);
    }
    std::string name;
};

int main()
{
    std::string x = "foo";
    foo(x)("bar")("baz");
    return 0;
}

Dies kompiliert einwandfrei mit clang ++, aber g ++ gibt den folgenden Fehler aus:

runme.cpp: In function ‘int main()’:
runme.cpp:21:11: error: conflicting declaration ‘foo x’
    foo(x)("bar")("baz");
        ^
runme.cpp:20:17: error: ‘x’ has a previous declaration as ‘std::string x’
    std::string x = "foo";

Wenn ich in Zeile 21 ein Paar Klammern hinzufüge, ist g ++ glücklich:

(foo(x))("bar")("baz");

Mit anderen Worten, g ++ interpretiert diese Zeile als:

foo x ("bar")("baz");

Denkt, es ist ein Fehler in g ++, aber ich wollte noch einmal die Standard-Experten fragen, welcher Compiler hat das falsch verstanden?

PS: gcc-4.8.3, clang-3.5.1

Antworten auf die Frage(4)

Ihre Antwort auf die Frage