C++ 参数的Koenig查找

C++ 参数的Koenig查找,c++,argument-dependent-lookup,C++,Argument Dependent Lookup,Koenig查找参数的想法是一件坏事吗 通过ADL,我们有: namespace foo { struct bar {}; void baz(bar); } baz(foo::bar()); 为什么我们没有这样的东西: namespace foo { struct bar {}; void baz(bar); } // namespace foo foo::baz(bar()); namespace foo { struct bar {}; void ba

Koenig查找参数的想法是一件坏事吗

通过ADL,我们有:

namespace foo
{
    struct bar {};
    void baz(bar);
}

baz(foo::bar());
为什么我们没有这样的东西:

namespace foo
{
  struct bar {};
  void baz(bar);
} // namespace foo

foo::baz(bar());
namespace foo
{
  struct bar {};
  void baz(bar);
} // namespace foo

foo::baz(bar());
Koenig查找参数的想法是一件坏事吗

绝对不是。它允许将非成员API放置在它所属的位置:与您的类型相同的名称空间;在调用函数时,它不会强制用户知道名称空间。
考虑编写<代码>排序(开始(VEC),结束(VEC))是多么方便;<代码>与std::sort(std::begin(vec)、std::end(vec))相反

它也是重载运算符时必须具备的功能

为什么我们没有这样的东西:

namespace foo
{
  struct bar {};
  void baz(bar);
} // namespace foo

foo::baz(bar());
namespace foo
{
  struct bar {};
  void baz(bar);
} // namespace foo

foo::baz(bar());

因为它很容易比相反的更模棱两可。如果
foo::baz
对于不同名称空间中的
bar
重载,该怎么办?如果不完全限定它,就不可能用另一个
条调用它。

关注非重复部分,为什么不
foo::baz(bar())?简单的原因是,在C++中,解析树总是被处理的最底层。函数名的名称查找取决于函数参数,而不是相反,就像重载解析取决于参数类型而不是返回类型一样

Koenig查找参数的想法是一件坏事吗

一点也不。考虑运算符重载的情况,可以使用在不同命名空间中定义的运算符。

namespace foo
{
    struct bar {};
    bar operator+ (const bar& lhs, const bar&rhs);
}
使用ADL,我们可以编写

foo::bar b1, b2;
auto b3 = b1 + b2; // natural as operator
没有ADL,我们必须写作

auto b3 = foo::operator+(b1, b2); // unnatural
作为旁注,STL的所有重载运算符都在名称空间
std
中定义。没有ADL,我们甚至可以称之为直截了当

此外,如果没有ADL,模板将面临挑战

template <typename T>
T add(const T& lhs, const T& rhs) {
    return What_Namespace::operator+(lhs, rhs); // how to deduce the name of namespace?
}
模板
T添加(常数T&lhs、常数T&rhs){
返回What_Namespace::operator+(lhs,rhs);//如何推断名称空间的名称?
}

这不是@Rhymoid的翻版吗?如果不是第二个问题,我会说是的。