The following code compiles fine on with GCC 4.8.5 and Clang 3.9.1 on my CentOS system, but does not compile with anything (GCC, Clang) on my MacOS system. They are both 64-bit systems. I guess that it comes from the different standard library used by those systems.
#include <iostream>
#include <cstdint>
std::int32_t f(std::int32_t a) { return 0; }
std::uint32_t f(std::uint32_t a) { return 1; }
std::int64_t f(std::int64_t a) { return 2; }
std::uint64_t f(std::uint64_t a) { return 3; }
int main() {
const std::size_t n = 0;
std::cout << f(n) << std::endl;
return 0;
}
On MacOS, it complains about ambiguous overloading. I am surprised as I thought that std::size_t and std::uint64_t are the same on 64-bit systems.
>> clang++ -std=c++11 main.cpp -o main
main.cpp:12:16: error: call to 'f' is ambiguous
std::cout << f(n) << std::endl;
^
main.cpp:4:14: note: candidate function
std::int32_t f(std::int32_t a) { return 0; }
^
main.cpp:5:15: note: candidate function
std::uint32_t f(std::uint32_t a) { return 1; }
^
main.cpp:6:14: note: candidate function
std::int64_t f(std::int64_t a) { return 2; }
^
main.cpp:7:15: note: candidate function
std::uint64_t f(std::uint64_t a) { return 3; }
^
1 error generated.
Even though this example looks stupid, I really need to overload f() for signed/unsigned and 32/64-bit integers in my real application and their behaviour must depend on the size of the integer as I am playing with bits. What should I do?
Simple answer: do not call f with std::size_t - call it with one of the exact types accepted by f.
Alternative answer: you only care about signedness and bit count. Use std::enable_if with all possible combinations:
template <typename T, bool Signed, int Size>
using enable_if_sd =
typename std::enable_if<
std::is_signed<T>{} == Signed && sizeof(T) * CHAR_BIT == Size
>::type;
template <typename T>
void f(T, enable_if_sd<T, true, 32>* = nullptr)
{
std::cout << "signed 32-bit\n";
}
template <typename T>
void f(T, enable_if_sd<T, true, 64>* = nullptr)
{
std::cout << "signed 64-bit\n";
}
template <typename T>
void f(T, enable_if_sd<T, false, 32>* = nullptr)
{
std::cout << "unsigned 32-bit\n";
}
template <typename T>
void f(T, enable_if_sd<T, false, 64>* = nullptr)
{
std::cout << "unsigned 32-bit\n";
}
coliru example
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With