C++ 名称查找、实例化点(POI)和基本类型

C++ 名称查找、实例化点(POI)和基本类型,c++,name-lookup,C++,Name Lookup,以下代码针对X编译,但不针对double编译: struct X{}; void foo(double); void foo(X); namespace NN { struct A{}; void foo(A) { foo(double{}); // error: foo not found foo(X{}); } } 这里的问题似乎是,ADL对X有利,但对双倍不利。可以通过将foo(A)移出名称空间NN来解决这个问题。但是,如果您需要将名称lokup延迟到POI(如以下代

以下代码针对X编译,但不针对double编译:

struct X{};

void foo(double);
void foo(X);

namespace NN { 
struct A{};
void foo(A)
{
  foo(double{});  // error: foo not found
  foo(X{});
}

}

这里的问题似乎是,ADL对X有利,但对双倍不利。可以通过将
foo(A)
移出
名称空间NN
来解决这个问题。但是,如果您需要将名称lokup延迟到POI(如以下代码段所示),这会带来麻烦:

void foo(double);

template<class T>
void bar(T x) { foo(x); }

namespace NN {
template<class T> struct A {};

template<class T>
void foo(const A<T>& x)
{
  using ::foo;  // this is required
  foo(T{});
}

}

void baz() { bar(NN::A<double>{}); }
void foo(双倍);
模板
空条(tx){foo(x);}
名称空间NN{
模板结构A{};
模板
无效foo(施工图A和x)
{
using::foo;//这是必需的
foo(T{});
}
}
void baz(){bar(NN::A{});}
在这里,您无法将
void foo(const A&x)
移出
名称空间NN
,因为此时bar无法找到正确的foo(并且无法编译)。 我想出的打破这个循环的唯一解决方案是在
foo
重载中显式添加
using::foo

问题:这是这个问题的标准解决方案还是有更好的解决方案

有人可能会说,在foo实现中可能需要一个名称空间列表。OTOH,可能它只对基本类型有必要,因为对于其他类型(即使在全局范围内),适当的函数在重载集中