跨命名空间覆盖运算符

Override operator across namespaces

这个问题是关于 C++03 的。

在我的命名空间中,我从不同的命名空间中键入了一个 class,然后尝试为该 class 重载一个运算符。我知道 typedef 只是一个别名而不是一个新类型,因此当 ADL 启动时我的重载没有被使用。起初这对我来说并不直观。我想知道是否有办法 "select" 我的过载,或者以某种方式 "guide" 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;
}

在这里,我使用来自 ::my 的对象调用 other::f(),即使 obj 实际上是 boost 中的 class 的类型定义。这输出:Boost implementation。我该怎么做才能让 My implementation 变成 运行?标记为 // *** 的行似乎可以做到这一点,但我宁愿 other::f() 不关心模板参数来自哪些命名空间。

您可以通过在您自己的文件中重载使用相同命名空间的函数来劫持 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;
   }
}