Why compiler writes

error: call to member function 'foo' is ambiguous

After all, I clearly indicated the literal type unsigned long long ?

 class A { using LL = long long; public: void foo(unsigned LL) {} void foo(LL) {} }; int main() { A a; a.foo(42ull); } 

    2 answers 2

    Here

     void foo(unsigned LL) {} 

    LL should be interpreted as an unsigned int function parameter. And further, since you have functions from unsigned int and long long , and you pass unsigned long long - there is no exact match, and the call is ambiguous ...

     class A { using LL = long long; using ULL = unsigned long long; public: void foo(ULL) {} void foo(LL) {} }; 

    and it will work :)

    typedef is not a preprocessor, attaching unsigned to the type so defined does not work.

      In fact, the first version of the overloaded member function foo has a parameter of type unsigned int , and not an unsigned long long int , as you probably wanted to ask. In this case, LL is the name of the parameter, not the typedef-name .

      dcl.spec # 3 :

      It is interpreted if it’s not necessary to know how it’s been in the decl-specifier-seq. -specifier-seq.

      Thus, the compiler encounters 2 candidates during the overload resolution : void foo(unsigned int) and void foo(long long int) , both of which require integral conversion , therefore they have the same rank, and the compiler produces the message described by you.