Join the Stack Overflow Community
Stack Overflow is a community of 6.7 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

How does find_type know where the function typemap is?
The argument it receives is not from that namespace, it's from the std namespace!

#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, "");

How can this code work? What is the rule allowing this?

I tested it with GCC 6.3 and clang 3.9.1.

share|improve this question
6  
The parameter type of the template parameter T from the struct find_type is std::unique_ptr<test::Test>. std::unique_ptr considers the test::Test template parameter for ADL, and thus, finds the typemap function in the test NS – SebTu 12 hours ago
up vote 16 down vote accepted

In the C++ standard 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.

The argument of typemap is std::unique_ptr<test::Test>, so namespace test is considered for name look up.

share|improve this answer

The argument it receives is not from that namespace, it's from the std namespace!

Not all of it!

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

This is:

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

There's a test:: in there, so the namespace test is searched too.

share|improve this answer
    
Thanks for that explanation. It completes the other answer really well. – Guillaume Racicot 12 hours ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.