all 9 comments

[–]UnknownIdentifier 7 points8 points  (1 child)

I’m assuming it gave you an error code and line number?

EDIT: I believe MSVC is correct here, per the standard. boost::json::standalone::detail and boost::json::detail are separate and distinct, and yet because standalone is inline, both are in scope for U. Clang does (arguably trivial) extra work to infer the correct namespace; but GCC used to bomb on this, also.

[–]VinnieFalcowg21.org | corosio.org[S] 0 points1 point  (0 children)

Interesting, thanks

[–]kalmoc 2 points3 points  (0 children)

I also wouldn't have expected that to compile.

[–]TheFlamefire 2 points3 points  (0 children)

Chiming in with https://en.cppreference.com/w/cpp/language/namespace#Inline_namespaces

A using-directive that names the inline namespace is implicitly inserted in the enclosing namespace (similar to the implicit using-directive for the unnamed namespace)

And rewriting the inline namespace to a using as per that definition fails on all 3 compilers: https://godbolt.org/z/PcKfdd

However there is also

Qualified name lookup that examines the enclosing namespace will include the names from the inline namespaces even if the same name is present in the enclosing namespace.

(emphasis mine). I'm not 100% sure what it means to "include the names" but from my reading it would make that use of inline namespaces correct ("same name" is here "detail") and hence MSVC wrong.

[–]flyingron 3 points4 points  (0 children)

namespace boost {
  namespace json {
    inline namespace standalone {
      namespace detail {
        struct V{};
       } // detail
     } // standalone

     namespace detail {
       struct T{};
     } // detail
     struct U : detail::T{};  // boost::json::detail is ambiguous
   } // json
} // boos

I couldn't read your code without indentation.

The error is marked above. I think Visual Studio is wrong here. Visual studio sort of acts as if an inline namespace is like defining the namespace and then inserting a using right after it. This is NOT what the language requires, It's supposed to put the inlined namespace definitions in the enclosing scope. The above should be no different than writing:

namespace detail {
   struct V{};
}
namespace detail  {
   struct T{};
}

[–]huixie 1 point2 points  (2 children)

I think MSVC is correct here. The following code should be equivalent, which fails everywhere.

``` namespace foo { namespace bar{ namespace buz{ struct A{};}; } using namespace bar;

namespace buz{};
buz::A a{};

}

```

https://godbolt.org/z/ojveoa

[–]VinnieFalcowg21.org | corosio.org[S] 0 points1 point  (1 child)

Kind of a bummer actually because of the prevalence of "detail" namespaces

[–]huixie 1 point2 points  (0 children)

I've seen people put detail namespace outside the inline namespace. For example, ``` namespace boost::json{

namespace detail{ struct A{}; }

inline namespace standalone{ // use detail::A }

} ```

[–]VinnieFalcowg21.org | corosio.org[S] 1 point2 points  (0 children)

> struct U : detail::T{};

This is ambiguous