Trying to understand how an overloaded function is selected

I have the following program:

#include <iostream>

namespace detail {

    template <class T> char test(int T::*)
    {
       std::cout << "Came to one\n";
       return 0;
    }

    template <class T> int test(...)
    {
       std::cout << "Came to two\n";
       return 0;
    }
}

struct A {};

int main()
{
   detail::test<A>(0);
   detail::test<int>(0);
}

When testing with g ++ 4.8.2, it produces the following output:

Came to one
Came to two

My question is: why is the first version detail::testuniquely selected for the first call?

Update

In the absence of the first version, the details::testcode from maincompiles fine. When it is, the compiler thinks this is a better match for detail::test<A>()than the second.

Update 2

After reading the pointer to an element, it is well formed even for incomplete types or without members of the assigned type. I tried the following and it works.

struct A;

int main()
{
   detail::test<A>(0);
   detail::test<int>(0);
}

In the C ++ 11 standard, there are many places for disclosing concepts that I would not even think about.

+4
2

, . test, , . , ( ).


:

8.3.3 [dcl.mptr]/2 .

14.8.2 [temp.deduct]/8:

, .

:

" T", T .

, 13.3.3.2. [over.ics.rank] (...) :

2 ( 13.3.3.1)

- (13.3.3.1.1) , ,

- (13.3.3.1.2) , (13.3.3.1.3).

detail::test<A>(0); , , . detail::test<int>(0); .

+10

, - .

+2

Source: https://habr.com/ru/post/1546646/


All Articles