tag near mva and c++ c++11 language-lawyer argument-dependent-lookup

c++ - near - mva



¿Por qué este caso de ADL está funcionando? (2)

¿Cómo sabe find_type dónde está la función typemap ?
El argumento que recibe no proviene de ese espacio de nombres, sino del std nombres 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, "");

¿Cómo puede funcionar este código? ¿Cuál es la regla que permite esto?

Lo probé con GCC 6.3 y clang 3.9.1.


El argumento que recibe no proviene de ese espacio de nombres, sino del espacio de nombres estándar.

¡No todo!

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

Esto es:

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

Hay una test:: allí, por lo que también se busca la test del espacio de nombres.


En el estándar C ++ N4618 §3.4.2 [basic.lookup.argdep] (2.2)

Si T es un tipo de clase (incluidas las uniones), sus clases asociadas son: la clase en sí misma; la clase de la que es miembro, en su caso; y sus clases básicas directas e indirectas. Sus espacios de nombres asociados son los espacios de nombres de cierre más internos de sus clases asociadas. Además, si T es una especialización de plantilla de clase, sus espacios de nombres y clases asociados también incluyen: los espacios de nombres y clases asociados con los tipos de argumentos de plantilla proporcionados para los parámetros de tipo de plantilla (excluyendo los parámetros de plantilla de plantilla); los espacios de nombres de los cuales cualquier argumento de plantilla de plantilla son miembros; y las clases de las cuales todas las plantillas miembro utilizadas como argumentos de plantilla de plantilla son miembros.

El argumento de typemap es std::unique_ptr<test::Test> , por lo que la test espacio de nombres se considera para la búsqueda de nombres.