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_t
is unsigned long
, not unsigned long long
.
You may be interested in https://en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models .
Why does Clang and GCC complain about the very last example?
They tell you why - the call is ambiguous, it is not clear which overload to choose.
Shouldn't it be the same as the third example?
No. In the third case class A
has a unsigned long long
overload. In the last case class B
does not have unsigned long long
overload.