std::(customization point) 是否调用最合适的重载?

xsk*_*xzr 5 c++ overloading c++-standard-library argument-dependent-lookup c++20

从 C++20 开始,在[namespace.std]/7 中引入了定制点的概念:

除了在命名空间 std 或命名空间 std 内的命名空间中,程序可以为指定为自定义点的任何库函数模板提供重载,前提是 (a) 重载的声明依赖于至少一个用户定义的类型和 (b ) 重载满足自定义点的标准库要求。[ 注意:这允许对自定义点的(限定或非限定)调用为给定参数调用最合适的重载。— 尾注 ]

注释部分(注意强调的词“合格”)是否意味着std::f将自动调用最合适的重载fifstd::f是自定义点?

一个真实的例子是std::swap,这是一个指定的定制点。这是否意味着从 C++20 开始,我们可以std::swap(a, b)直接编写而不是using std::swap; swap(a, b);?

Bar*_*rry 3

一个真实的例子是std::swap,它是指定的定制点。这是否意味着从 C++20 开始,我们可以std::swap(a, b)直接编写而不是使用std::swap; swap(a, b);

不。std::swap本身并没有获得任何权力。它仍然只是一个函数模板,所以如果你直接调用它,你就是......直接调用它。没有ADL什么的。

重点是说应该如何选择定制点。也就是说,你写:

namespace N { // not std
    void swap(Foo&, Foo&);
}
Run Code Online (Sandbox Code Playgroud)

不是:

namespace std {
    void swap(N::Foo&, N::Foo&);
}
Run Code Online (Sandbox Code Playgroud)

也不:

namespace std {
    template <>
    void swap(N::Foo&, N::Foo&);
}
Run Code Online (Sandbox Code Playgroud)

然而,C++20 确实引入了很多新的东西,称为定制点对象,您可以直接使用它们来做这种事情。CPOswap是拼写的std::ranges::swap(同样,所有有用范围的东西都有 CPO... ranges::beginranges::end等)。