Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to use nested namespace to avoid ambiguity?

I have the following operators defined in the corresponding namespaces:

namespace literals
{

constexpr ID operator"" _ID(const unsigned long long dyngateID)
{
    // ...
    // return a constructed id
}

namespace multiplied
{

constexpr ID operator"" _ID(const unsigned long long dyngateID)
{
    // ...
    // return an id constructed in a specific way
}

} // namespace multiplied
} // namespace literals

In a .cpp file I would like to use both functions, hence I’ve declared using namespace literals and when I am declaring using namespace multiplied in a concrete function I am getting ambiguous call to overloaded function compile error. How can I differentiate these functions?

Test.cpp

using namespace literals;

void f()
{
    // here I am using literals' _ID which is fine
    const Type id{1_ID};
}
void g()
{
    // here I want to use multiplied's _ID, but obviously I am failing to do so
    using namespace multiplied;
    const Type id{1_ID};
}

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

The name lookup rules for using namespace are such that the declarations introduced by it appear to be located in the most-inner namespace including both the current namespace and the target namespace of using namespace.

Therefore it is no good to disambiguate based on use in an inner scope.

Instead you can import the declaration itself with a using declaration:

void g()
{
    using multiplied::operator""_ID;
    const Type id{1_ID};
}

This will behave as if the operator was declared in the scope, so that name lookup will stop there and won’t look at the declaration imported by the outer using namespace.


Alternatively, you can call the user-defined literal operator directly with a qualified call:

void g()
{
    const Type id{multiplied::operator""_ID(1)};
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading