I have this code:
#include <string>
#include <cstdint>
typedef unsigned long long u64;
struct A{
A(int a) : m_a(a){}
A(u64 a) : m_a(a){}
A(double a) : m_a(a){}
u64 m_a;
};
struct B{
B(int b) : m_b(b){}
B(uint64_t b) : m_b(b){}
B(double b) : m_b(b){}
uint64_t m_b;
};
int main(){
// This works
unsigned long long a = std::stoull("10000");
// And this
auto a2 = A(a);
// And this
auto a3 = A(std::stoull("10000"));
// This works
uint64_t b = std::stoull("10000");
// And this
auto b2 = B(b);
// But not this?
auto b3 = B(std::stoull("10000"));
return 0;
}
Why does Clang and GCC complain about the very last example? Shouldn't it be the same as the third example? Can someone explain what is going on? What C++ features/rules are at play here?
On the platform you are compiling,
uint64_tisunsigned long, notunsigned long long.You may be interested in https://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models .
They tell you why - the call is ambiguous, it is not clear which overload to choose.
No. In the third case class
Ahas aunsigned long longoverload. In the last case classBdoes not haveunsigned long longoverload.