为什么这个 ADL 案例有效?
Why this ADL case is working?
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)
If T is a class type (including unions), its associated classes are: the class itself; the class of which it is
a member, if any; and its direct and indirect base classes. Its associated namespaces are the innermost
enclosing namespaces of its associated classes. Furthermore, if T is a class template specialization,
its associated namespaces and classes also include: the namespaces and classes associated with the
types of the template arguments provided for template type parameters (excluding template template
parameters); the namespaces of which any template template arguments are members; and the classes
of which any member templates used as template template arguments are members.
typemap
的参数是 std::unique_ptr<test::Test>
,因此命名空间 test
被考虑用于名称查找。
The argument it receives is not from that namespace, it's from the std namespace!
不是全部!
using type = decltype(typemap(std::declval<T>()));
这是:
using type = decltype(typemap(std::declval<std::unique_ptr<test::Test>>()));
里面有一个test::
,所以命名空间test
也被搜索了。
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)
If T is a class type (including unions), its associated classes are: the class itself; the class of which it is a member, if any; and its direct and indirect base classes. Its associated namespaces are the innermost enclosing namespaces of its associated classes. Furthermore, if T is a class template specialization, its associated namespaces and classes also include: the namespaces and classes associated with the types of the template arguments provided for template type parameters (excluding template template parameters); the namespaces of which any template template arguments are members; and the classes of which any member templates used as template template arguments are members.
typemap
的参数是 std::unique_ptr<test::Test>
,因此命名空间 test
被考虑用于名称查找。
The argument it receives is not from that namespace, it's from the std namespace!
不是全部!
using type = decltype(typemap(std::declval<T>()));
这是:
using type = decltype(typemap(std::declval<std::unique_ptr<test::Test>>()));
里面有一个test::
,所以命名空间test
也被搜索了。