对于类型为类模板特化的参数,ADL背后的基本原理是什么?

wit*_*osx 9 c++ templates argument-dependent-lookup

我花了一些时间试图意识到为什么我的代码不能编译,我已经意识到在C++ Argument Dependent Lookup中使用模板typename参数来确定名称查找范围.

#include <string>
#include <functional>

namespace myns {

    template<typename T>
    struct X
    {};

    template<typename T>
    auto ref(T) -> void
    {}

} // namespace myns

auto main() -> int
{
    ref(myns::X<int>{});
    ref(myns::X<std::string>{}); // error: call to 'ref' is ambiguous
}
Run Code Online (Sandbox Code Playgroud)

所以前面的ref调用编译,因为myns::X<int>myns::ref考虑,而后者不编译,因为它发现myns::ref()以及std::ref

我的问题是这有用吗?我为什么需要这个?你有什么想法,例子吗?现在我只能看到上面例子中的缺点,它会引入不必要的歧义.

son*_*yao 7

假设您将所有内容放入您自己的命名空间,包括用户定义的类,以及std::vector作为参数的函数.即

namespace myns {

    struct X {};

    template<typename T>
    auto my_func(const std::vector<T>&) -> void
    {}

} // namespace myns
Run Code Online (Sandbox Code Playgroud)

那么你可以利用ADL也考虑提供的类型作为模板参数的事实,并写下:

my_func(std::vector<myns::X>{});
Run Code Online (Sandbox Code Playgroud)

另一方面:

my_func(std::vector<int>{});        // error, can't find my_func
myns::my_func(std::vector<int>{});  // fine
Run Code Online (Sandbox Code Playgroud)

回到原来的问题,这里的教训是不使用标准库中的名称,只会使代码混乱.