为什么这个 ADL 案例有效



find_type怎么知道函数typemap在哪里?
它收到的参数不是来自该命名空间,而是来自std命名空间!

#include <type_traits>
#include <memory>
namespace lib {
    template<typename T>
    struct find_type {
        using type = decltype(typemap(std::declval<T>()));
    };
}
namespace test {
    struct Test {};
    auto typemap(std::unique_ptr<Test>) -> int;    
}
static_assert(std::is_same<int, lib::find_type<std::unique_ptr<test::Test>>::type>::value, "");

这段代码如何工作?允许这样做的规则是什么?

我用GCC 6.3和clang 3.9.1测试了它。

在C++标准 N4618 §3.4.2 [basic.lookup.argdep] (2.2(

如果 T 是类类型(包括联合(,则其关联的类为:类本身;它所在的类 成员(如有(;及其直接和间接基类。其关联的命名空间是最里面的 包含其关联类的命名空间。此外,如果 T 是类模板专用化, 其关联的命名空间和类还包括:与 为模板类型参数提供的模板参数的类型(不包括模板模板( 参数(;任何模板模板参数都是其成员的命名空间;和类 其中用作模板模板参数的任何成员模板都是成员。

typemap的参数是std::unique_ptr<test::Test>的,所以命名空间test被考虑用于名称查找。

它收到的参数不是来自该命名空间,而是来自 std 命名空间!

不是全部!

using type = decltype(typemap(std::declval<T>()));

这是:

using type = decltype(typemap(std::declval<std::unique_ptr<test::Test>>()));

那里有一个test::,因此也会搜索命名空间test

最新更新