Joe Ruether
Joe Ruether

Reputation: 25

Override operator across namespaces

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

Answers (1)

R Sahu
R Sahu

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

Related Questions