Reputation: 394
I am using a library that is under a namespace, let's call it Hello.
namespace Hello {
template<class T>
void World(std::ostream& os, const T& t) {
os << t;
}
}
The class T
is something like std::array<int,10>
and I also write an ostream overload function for it. However, calling Hello::World(arr)
leads to compile errors that say the compiler cannot find the overload for operator<<()
.
After some search, I come up with a solution that explains this situation. How does the operator overload resolution work within namespaces? and Name resolution of functions inside templates instantiated with qualified types.
So we can simplify the situation like this.
void f(int) {}
void f(int,int) {}
namespace Hello {
using ::f;
void f(int,int,int) {}
void World()
{
f(100);
f(100, 200);
f(100, 200, 300);
}
};
int main()
{
Hello::World();
return 0;
}
Without the using ::f;
line, this code fails to be compiled since the name f
can hide ALL of the functions with the same name in the global namespace.
Now that this is my problems:
namespace Hello { .... }
is in the library, I shall not modify it. That is, I cannot modify the implementation inside World()
. The only solution is to put a line namespace Hello { using ::f; }
somewhere in my code. Is it a good practice, or there is a more elegant solution?f(int)
and not f(int,int)
?Upvotes: 2
Views: 888
Reputation: 12263
Is it a good practice, or there is a more elegant solution?
IMHO, you can use it with third party library. It is clear and expressive enough. It would be better if you could write:
void World() {
::f(100); // f from global namespace
::f(100, 200); // f from global namespace
f(100, 200, 300); // f NOT from global namespace
}
because then it is clearly visible which function is and which is not from the global namespace but this solution does not work for you since you cannot modify implementation of World
function.
Can I only import
f(int)
and notf(int, int)
?
Yes. You can do the following in order to import only f(int)
function:
void f(int) {}
namespace Hello {
using ::f; // only void f(int) is defined before this line
// therefore, it is the only overload being imported to the Hello namespace
}
void f(int,int) {}
UPDATE
If you want to import only one overload of an operator<<
, not an ordinary function, then you could wrap each overload in a separate namespace like this:
namespace XX {
struct X {
int x;
};
std::ostream& operator<<(std::ostream& os, X const& x) {
return os;
}
}
namespace YY {
std::ostream& operator<<(std::ostream& os, Y const& y) {
return os;
}
struct Y {
double y;
};
}
namespace Hello {
using ::XX::X;
using ::XX::operator<<;
using ::YY::Y;
}
Check it out live.
Upvotes: 2