当我用C++编程时,我通常倾向于使用std::
前缀组件,如std::cout
、std::cin
等,而不是编写using namespace std;
。
标准库的许多组件(在std中)以非限定的方式调用swap,以允许调用非基本类型的自定义重载,而不是这个泛型版本:在与为其提供自定义重载的类型相同的命名空间中声明的swap自定义重载通过在此泛型版本上进行依赖于参数的查找来选择。
但是在所有关于ADL的资料中,他们只提到了std::swap
,在使用的时候有没有其他类似的函数需要注意,或者对于所有其他的函数我应该使用完全限定名,或者对于std::
中的每个函数我都应该使用非限定名?
编辑:(我最初的问题措辞不清楚,以下是我写这个问题时的确切意图。)
C++标准库中是否有其他函数是基于ADL的定制的热门候选对象,就像std::swap
一样,因此当我使用它们时,我必须谨慎地使用using std::foo; foo();
形式,而不是直接调用std::foo();
?
1条答案
按热度按时间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&)
。你可以写但你没有你习惯于写
而这只是由于ADL才起作用。
PPS:即使对于
std::swap
,"* 不应该 * 使用std::
作为前缀"也是不对的。如上所述,有时候您确实希望使用ADL,有时候您不希望使用ADL。这个决定不是针对每个函数,而是针对每个用例。如果您编写了交换两个对象的代码,并且出于某种原因您希望调用std::swap
,而不调用其他任何东西,然后你调用std::swap
,如果你想使用ADL,那么你就使用ADL。