为什么这个ADL案例有效?

Gui*_*cot 19 c++ language-lawyer argument-dependent-lookup c++11

怎么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, "");
Run Code Online (Sandbox Code Playgroud)

这段代码怎么样?允许这个的规则是什么?

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

Oli*_*liv 19

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

如果T是类类型(包括联合),则其关联的类是:类本身; 它所属的成员,如果有的话; 及其直接和间接基类.其关联的命名空间是其关联类的最内部封闭命名空间.此外,如果T是类模板特化,则其关联的名称空间和类还包括:与模板类型参数(模板模板参数除外)提供的模板参数类型相关联的名称空间和类 ; 任何模板模板参数都是成员的名称空间; 以及用作模板模板参数的任何成员模板的类都是成员.

参数typemapstd::unique_ptr<test::Test>,所以命名空间test被认为是名称查找.


Lig*_*ica 14

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

不是全部!

using type = decltype(typemap(std::declval<T>()));
Run Code Online (Sandbox Code Playgroud)

这是:

using type = decltype(typemap(std::declval<std::unique_ptr<test::Test>>()));
Run Code Online (Sandbox Code Playgroud)

那里有一个test::,所以命名空间test也被搜索到了.