• Namespace vs. class ambiguity: three compilers - three different outcom

    From Andrey Tarasevich@21:1/5 to All on Sat Sep 7 11:24:31 2024
    Hello

    It is illegal to just flat-out declare a class and a namespace with
    identical names in the same scope

    namespace N {}
    class N {}; // <- Not allowed

    However, one can try to circumvent the direct restriction by means of using-directive or using-declaration

    #include <iostream>

    namespace N
    {
    void foo() { std::cout << "namespace" << std::endl; }
    }

    namespace X
    {
    struct N
    {
    static void foo() { std::cout << "class" << std::endl; }
    };
    }

    using X::N;
    // or
    // using namespace X;

    int main()
    {
    N::foo();
    }

    GCC is perfectly happy with either version of this code (both
    using-declaration and using-directive versions are OK). It simply
    resolves the call to the "namespace" version of `foo()`.

    Clang issues an error: it complains about the call being ambiguous. I.e.
    the error is issued at the point of the call.

    MSVC++ issues an error for `using X::N;` at the point of
    using-declaration: it basically says that `N` already exists in this
    scope. But if we switch to `using namespace X;` version, MSVC++ will
    exhibit Clang-like behavior: complain about ambiguity at the point of
    the call.

    So, who is right here?

    --
    Best regards,
    Andrey

    P.S. We can rewrite `main` as

    int main()
    {
    using T = struct N;
    T::foo();
    }

    This will keep both GCC and Clang happy and direct the call to the
    "class" version of `foo()`. It will work in both using-declaration and using-directive versions of the code

    This will work in MSVC++ as well, but obviously only with
    using-directive version (since using-declaration triggers an error earlier).

    Again, who is right here?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)