标准C++库中的哪些函数不应使用std:作为前缀:何时使用?

klsxnrf1  于 2023-01-18  发布在  其他
关注(0)|答案(1)|浏览(173)

当我用C++编程时,我通常倾向于使用std::前缀组件,如std::coutstd::cin等,而不是编写using namespace std;
标准库的许多组件(在std中)以非限定的方式调用swap,以允许调用非基本类型的自定义重载,而不是这个泛型版本:在与为其提供自定义重载的类型相同的命名空间中声明的swap自定义重载通过在此泛型版本上进行依赖于参数的查找来选择。
但是在所有关于ADL的资料中,他们只提到了std::swap,在使用的时候有没有其他类似的函数需要注意,或者对于所有其他的函数我应该使用完全限定名,或者对于std::中的每个函数我都应该使用非限定名?

编辑:(我最初的问题措辞不清楚,以下是我写这个问题时的确切意图。)

C++标准库中是否有其他函数是基于ADL的定制的热门候选对象,就像std::swap一样,因此当我使用它们时,我必须谨慎地使用using std::foo; foo();形式,而不是直接调用std::foo();

e5nqia27

e5nqia271#

假设你写了一个使用用户提供的类型的库,那么你可能想提供一个默认的实现来foo一个栏,但是同时你想让用户提供他们的自定义实现,因为他们可能更了解如何foo他们的自定义栏。
这正是std::swap在标准库中所发生的事情。依赖于ADL的代码在库中,它与自定义类型一起工作,直到示例化它才知道类型。它可以提供默认的std::swap,但同时允许用户提供自己的实现。
在你的用户代码中,当你知道类型时,你通常会想知道调用了什么函数,通常你知道是要调用my::swap还是std::swap,你不需要ADL来选择。
话虽如此,如果你一定要问这个问题,那么答案是:不要使用ADL。(我知道"如果你不得不问..."有点傻,但有时它应用得太好了)。即使在库代码中,你也不总是想启用ADL,或者允许它作为定制。即使你写了泛型代码,也可能有这样的情况,你需要你的方式来foo一个酒吧,而不允许用户定制它。这真的取决于。
简短回答:如果你想调用std::swap,那么调用std::swap。如果你想调用my::swap,那么调用my::swap。如果你想使用ADL,你会知道该怎么做。
PS:还有更多的ADL例子,你知道,但可能不知道。你几乎从来没有使用前缀std::当你调用一个运算符重载,例如std::string operator+(const std::string&,const std::string&)。你可以写

std::string a,b;
 auto c = std::operator+(a,b);

但你没有你习惯于写

auto c = a + b;

而这只是由于ADL才起作用。
PPS:即使对于std::swap,"* 不应该 * 使用std::作为前缀"也是不对的。如上所述,有时候您确实希望使用ADL,有时候您不希望使用ADL。这个决定不是针对每个函数,而是针对每个用例。如果您编写了交换两个对象的代码,并且出于某种原因您希望调用std::swap,而不调用其他任何东西,然后你调用std::swap,如果你想使用ADL,那么你就使用ADL。

相关问题