跨命名空间覆盖运算符

时间:2016-02-19 20:51:30

标签: c++ templates namespaces operator-overloading argument-dependent-lookup

这个问题与C ++ 03有关。

在我的命名空间中,我从不同的命名空间中键入一个类,然后尝试重载该类的运算符。我知道typedef只是一个别名而不是一个新类型,因此当我的重载中的ADL踢不使用时。起初这对我来说并不直观。我想知道是否有办法“选择”我的重载,或以某种方式“引导”ADL到正确的命名空间?

以下是一个简化的案例:

#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;
}

在这里,我使用other::f()中的对象调用::my,即使obj实际上是boost中类的typedef。这输出:Boost implementation。如何让My implementation运行?标记为// ***的行似乎是这样做的,但我宁愿不让other::f()关心模板参数来自哪些名称空间。

1 个答案:

答案 0 :(得分:1)

您可以通过在您自己的文件中重载使用相同命名空间的函数来劫持boost命名空间中的泛型实现。

继续在my命名空间中拥有自己的通用实现,然后添加:

namespace boost
{
   typedef some_type<int> typedefed_type;

   template<typename T>
   T& operator<<(T& os, typedefed_type const& obj)
   {
      return my::operator<<(os, obj);
   }
}

然后,您在<<命名空间中使用other运算符非常简单。

namespace other
{
   template<typename T>
   void f(T const& obj)
   {
      std::cout << obj << std::endl;
   }
}