Reputation: 626
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};
}
Upvotes: 0
Views: 280
Reputation: 76628
The name lookup rules for using namespace
are such that the declarations introduced by it appear to be located in the inner-most namespace scope enclosing both the current namespace scope and the target namespace scope.
Therefore it is no good to disambiguate based on the scoping of multiple reachable using namespace
statements.
Instead you can import the declaration 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)};
}
As another possibility you can always limit the scope of the using namespace
statements, so that only one of using namespace literals;
or using namespace literals::multiplied;
is reachable from any given scope using the operator, e.g.:
// no using namespace at this scope
void f()
{
using namespace literals;
const Type id{1_ID};
}
void g()
{
using namespace literals::multiplied;
const Type id{1_ID};
}
Upvotes: 3
Reputation: 1585
Consider the following code:
#include <iostream>
namespace one
{
int func(int num1, int num2)
{
return num1 * num2;
}
namespace two
{
int func(int num1, int num2)
{
return num1 * num2;
}
}
}
int f()
{
return one::two(1, 2) + 10;
}
int g()
{
return one::two::func(3, 4) + 10;
}
int main()
{
std::cout << f() << std::endl;
std::cout << g() << std::endl;
}
The above code will compile and run perfectly fine, and will work as expected, with f()
using one::func()
and g()
using one::two::func()
. If you have to write `using namespace one;' then you can do something like this:
using namespace one;
int f()
{
return func(1, 2) + 10;
}
int g()
{
return two::func(3, 4) + 10;
}
This will also result in the same output.
Upvotes: -1