使用另一个命名空间中的typedef进行ADL

Arm*_*yan 15 c++ typedef argument-dependent-lookup

我有这样的事情:

#include <iostream>
namespace N
{
   typedef std::pair<int, double> MyPair;
   std::ostream& operator << (std::ostream& o, MyPair const & mypair)
   {
      ///
   }
}

int main()
{
    N::MyPair pr;
    std::cout << pr;
}
Run Code Online (Sandbox Code Playgroud)

这自然不起作用,因为ADL找不到operator<<因为namespace NMyPair(不幸)相关联.Afaik可能不会添加到命名空间std,所以如果我选择operator <<在std中定义那将是非法的.那么......在这种情况下该怎么办?我不想明确限定operator <<,也不想写using namespace N.所以,问题是:

  1. 如何重构代码?
  2. 为什么ADL不会关联typedef的名称空间?严重的原因?这会很好,例如在这种情况下.谢谢

小智 4

  1. 您可以在命名空间 N 中创建自己的类型,可能继承自 std::pair。您可以添加“using namespace N;” 里面主要. 前者可能更有用。

  2. 因为类型是在另一个命名空间中定义的,不能同时定义在两个命名空间中。

例子:

namespace N { 
struct MyPair : std::pair<int, double> {
  MyPair(int first, double second) : std::pair<int, double>(first, second) {}
  // add defaults if desired: first=0, second=0.0
  // with defaults, you may want to make the ctor explicit or leave implicit

  // also, if desired and you don't use two defaults above:
  MyPair() : std::pair<int, double>(0, 0.0) {}

  // in 0x, you can "import" the base's ctors with a using declaration
};
}
Run Code Online (Sandbox Code Playgroud)

如果用作 std::pair 并不重要,您可以删除继承并重命名成员。当然,在任何一种情况下,您都可以添加其他方法,但如果保留继承,则可以使用“重命名方法”:

int      & foo()       { return first; }
int const& foo() const { return first; }
double      & bar()       { return second; }
double const& bar() const { return second; }
Run Code Online (Sandbox Code Playgroud)

  • @Roger:创建一个新类只是为了 ADL (3认同)
  • @Armen:嗯,事实并非如此。:) 这样想一下,是什么让你的 MyPair 类型特别呢?它很特别,因为您需要它的特殊输出格式。如何将 MyPair 与其他配对区分开来?您为其创建一个特殊类型。 (3认同)