static_pointer_cast
位于std
命名空间。然而,它也接受std
命名空间中的指针。
因此std::
合格呼叫和不合格呼叫都被接受。
哪一种是调用static_pointer_cast
的正确、更习惯的方式?
一般来说,如果您确切地知道要调用哪个函数,而不是允许自定义,我会尽量避免使用ADL,这意味着要避免非限定调用。
在这种情况下,不期望库为自己类型的shared_ptr
提供自己的static_pointer_cast
。您总是希望调用std
版本。直接调用std::static_pointer_cast
可以保证没有其他static_pointer_cast
会干扰。
如果你包含了一个库,它也声明了一些名为static_pointer_cast
的函数,而这个函数恰好对你的调用是可行的,并且比std
更适合或更专门于重载解析,如果你使用一个不合格的调用,你可能会不小心调用它。
我认为这在static_pointer_cast
的情况下不太可能成为一个问题,因为库不太可能以一种重载对正常的std::static_pointer_cast
调用是可行的,同时是更好的匹配的方式使用该名称,所有这些都没有意识到其含义。
但是以std::launder
为例,这似乎发生在一些代码库中(相反),当c++ 17引入时,std
重载被证明比以标准库类型作为参数的非限定调用中的库重载更匹配。
如果你看一下c++标准库的实现,你会发现它们严格遵循这条规则来避免非限定调用,并且只在标准期望用户能够自定义调用的地方使用它们。当然,对于非库代码,这可能不是一个重要的考虑因素。
但也要注意,在c++ 20之前,如果没有通过通常的非限定查找找到名为static_pointer_cast
的函数模板,那么使用显式模板参数列表(static_pointer_cast
需要)的非限定调用无论如何都会失败。因此,在c++ 20之前,如果没有事先的using
声明来导入函数,您实际上无法选择使用非限定调用。