Koenig 查找参数
Koenig lookup for arguments
Koenig 查找参数的想法是坏事吗?
有了 ADL,我们有:
namespace foo
{
struct bar {};
void baz(bar);
}
baz(foo::bar());
为什么我们没有这样的东西:
namespace foo
{
struct bar {};
void baz(bar);
} // namespace foo
foo::baz(bar());
Is idea of Koenig lookup for arguments a bad thing?
绝对不是。它允许将非成员 API 放置在它所属的位置:与您的类型相同的命名空间;它不会强制用户在调用函数时了解命名空间。
考虑一下 sort(begin(vec), end(vec));
与 std::sort(std::begin(vec), std::end(vec));
相比有多方便
当你重载运算符时,它也是必须的。
And why we don't have something like:
namespace foo
{
struct bar {};
void baz(bar);
} // namespace foo
foo::baz(bar());
因为它比相反的更容易含糊不清。如果 foo::baz
在不同的命名空间中为 bar
重载怎么办?如果没有完全限定它,你将无法与另一个 bar
一起调用它。
关注非重复部分,为什么不foo::baz(bar());
?原因很简单,在 C++ 中,解析树总是从下到上处理的。函数名称的名称查找取决于函数参数,而不是相反,就像重载决策取决于参数类型而不是 return 类型一样。
Is idea of Koenig lookup for arguments a bad thing?
完全没有。考虑运算符重载的场景,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?
}
Koenig 查找参数的想法是坏事吗?
有了 ADL,我们有:
namespace foo
{
struct bar {};
void baz(bar);
}
baz(foo::bar());
为什么我们没有这样的东西:
namespace foo
{
struct bar {};
void baz(bar);
} // namespace foo
foo::baz(bar());
Is idea of Koenig lookup for arguments a bad thing?
绝对不是。它允许将非成员 API 放置在它所属的位置:与您的类型相同的命名空间;它不会强制用户在调用函数时了解命名空间。
考虑一下 sort(begin(vec), end(vec));
与 std::sort(std::begin(vec), std::end(vec));
当你重载运算符时,它也是必须的。
And why we don't have something like:
namespace foo { struct bar {}; void baz(bar); } // namespace foo foo::baz(bar());
因为它比相反的更容易含糊不清。如果 foo::baz
在不同的命名空间中为 bar
重载怎么办?如果没有完全限定它,你将无法与另一个 bar
一起调用它。
关注非重复部分,为什么不foo::baz(bar());
?原因很简单,在 C++ 中,解析树总是从下到上处理的。函数名称的名称查找取决于函数参数,而不是相反,就像重载决策取决于参数类型而不是 return 类型一样。
Is idea of Koenig lookup for arguments a bad thing?
完全没有。考虑运算符重载的场景,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?
}