Reputation: 25
This question is in regards to C++03.
In my namespace, I typedef a class from a different namespace, then attempt to overload an operator for that class. I understand that typedef is just an alias and not a new type, therefore when ADL kicks in my overload is not used. This wasn't intuitive to me at first. I'm wondering if there is a way to "select" my overload, or somehow "guide" ADL to the correct namespace?
Below is a simplified case:
#include <iostream>
namespace boost
{
template<typename T>
struct some_type{};
template<typename T, typename U>
T& operator<<(T& os, some_type<U> const& obj)
{
os << "Boost implementation";
return os;
}
}
namespace my
{
typedef boost::some_type<int> typedefed_type;
template<typename T>
T& operator<<(T& os, typedefed_type const& obj)
{
os << "My implementation";
return os;
}
}
namespace other
{
template<typename T>
void f(T const& obj)
{
// using namespace my; // ***
std::cout << obj << std::endl;
}
}
int main(int argc, char* argv[])
{
my::typedefed_type obj;
other::f(obj);
return 0;
}
Here, I am calling other::f()
with an object from ::my
, even though obj
is really a typedef of a class in boost
. This outputs: Boost implementation
. What can I do to get My implementation
to run? The line marked // ***
seems to do it, but I would rather not have other::f()
care about what namespaces the template parameter came from.
Upvotes: 0
Views: 1876
Reputation: 206577
You can hijack the generic implementation in boost
namespace by overloading the function in your own file that uses the same namespace.
Continue to have your own generic implementation in my
namespace and then add:
namespace boost
{
typedef some_type<int> typedefed_type;
template<typename T>
T& operator<<(T& os, typedefed_type const& obj)
{
return my::operator<<(os, obj);
}
}
Then, your use of of the <<
operator can be simple in other
namespace.
namespace other
{
template<typename T>
void f(T const& obj)
{
std::cout << obj << std::endl;
}
}
Upvotes: 1