c++user-defined-literals

Qualify invocation of ambiguous UDL


I have two namespaces which both define the same User Defined Literals:

namespace foo {
    struct x{ unsigned long long i; };
    namespace literals {
        constexpr foo::x operator""_x(unsigned long long i) { return { i }; }
    }
}

namespace bar {
    struct x{ unsigned long long i; };
    namespace literals {
        constexpr bar::x operator""_x(unsigned long long i) { return { i }; }
    }
}

Is there some way I can use both in the same scope without ambiguity? For all other functions, I can just use fully qualified names:

std::vector<std::pair<foo::x, bar::x>> v = {
     { foo::x{ 3 }, bar::x{ 14 } }, 
};

But I cannot do the same for UDLs (unless I call them as regular functions foo::literals::operator""_x(3) which defeats their purpose as a shorthand):

namespace f = foo::literals;
namespace b = bar::literals;

std::vector<std::pair<foo::x, bar::x>> v = {
     { 3f::_x, 14b::_x }, 
};

In this case a solution I would go with is to construct v via a helper or IIFE [](const std::vector<unsigned long long, unsigned long long>&) -> std::vector<std::pair<foo::x, bar::x>>, but I wondered if there is some way to not give up on UDLs.


Solution

  • This does not appear to be possible, since UDLs have to be used using unqualified names. To disambiguate them, one can create an "alias":

    constexpr foo::x operator""_fx(unsigned long long i) {
        return foo::literals::operator""_x(i);
    }
    
    constexpr bar::x operator""_bx(unsigned long long i) {
        return bar::literals::operator""_x(i);
    }
    
    std::vector<std::pair<foo::x, bar::x>> v = {
         { 3_fx, 14_bx }, 
    };