Search code examples
c++templatesnamespacesc++17

Template specialization outside an inline namespace of a function defined inside the inline namespace


Is it valid C++ to do a template specialization of a function inside an inline namespace in the space outside the inline namespace?

For example, would this compile?

namespace A
{
    inline namespace A0
    {
        namespace B
        {
            template<typename T>
            T sum(T v1, T v2)
            {
                return v1 + v2;
            }
        }
    }
}

namespace A
{
    namespace B
    {
        template<>
        float sum<float>(float v1, float v2)
        {
            return v1 - v2; // Do something different
        }
    }
}

Currently, this code compiles with g++ 13.02, but not with MSVC 19.40 for c++17


Solution

  • https://eel.is/c++draft/namespace.def.general#2:

    In a named-namespace-definition D, the identifier is the name of the namespace. The identifier is looked up by searching for it in the scopes of the namespace A in which D appears and of every element of the inline namespace set of A. If the lookup finds a namespace-definition for a namespace N, D extends N, and the target scope of D is the scope to which N belongs.

    So the second time a namespace named B appears in your example:

    namespace A
    {
        namespace B
        {
            // ...
        }
    }
    

    The lookup finds the namespace A::A0::B, so that new namespace extends the first namespace named B, in exactly the same way as if you had written:

    namespace A::inline A0::B {
       // ...
    }
    

    Thus when sum is looked up when named in the explicit specialization, it finds the template A::A0::B::sum, which it can specialize fine.