Koenig查询参数

问题描述:

是否认为Koenig查找参数是一件坏事?Koenig查询参数

与ADL进行,我们有:

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

baz(foo::bar()); 

,为什么我们没有这样的:

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

foo::baz(bar()); 
+1

这不是一个重复的[“为什么ADL发明的?”](/问题/ 4276772 /为什么 - 是参数的依赖查对发明的?RQ = 1) – 2016-11-10 15:23:48

+1

@Rhymoid,如果不对于第二个问题,我会说是的。 – StoryTeller

专注于非重复部分,为什么不是foo::baz(bar());?简单的原因是,在C++中,分析树总是从下到上进行处理。函数名称的名称查找取决于函数参数,而不是其他方式,就像重载解析一样,取决于参数类型而不是返回类型。

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

绝对不是。它允许在其所属的非成员API中放置:与您的类型相同的名称空间;它不会强制用户在调用函数时知道名称空间。
考虑它是多么方便写sort(begin(vec), end(vec));而不是std::sort(std::begin(vec), std::end(vec));

这也是一个必须有当你重载运算符。

,为什么我们没有这样的:

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

foo::baz(bar()); 

因为它很容易比相对比较模糊。如果foo::baz在不同的命名空间中过载bar会怎么样?如果没有完全限定条件,您将无法使用其他bar进行调用。

是否认为Koenig查找参数是一件坏事?

根本不是。考虑操作符重载的场景,ADL可以使用在不同命名空间中定义的操作符。

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? 
}