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());
答
专注于非重复部分,为什么不是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?
}
这不是一个重复的[“为什么ADL发明的?”](/问题/ 4276772 /为什么 - 是参数的依赖查对发明的?RQ = 1) – 2016-11-10 15:23:48
@Rhymoid,如果不对于第二个问题,我会说是的。 – StoryTeller