以下代码在我的CentOS系统上使用GCC 4.8.5和Clang 3.9.1进行编译,但不能在我的MacOS系统上编译任何东西(GCC,Clang)。它们都是64位系统。我猜它来自这些系统使用的不同标准库。
#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;
}
在MacOS上,它抱怨模糊的重载。我很惊讶,因为我认为std::size_t
和std::uint64_t
在64位系统上是相同的。
>> 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.
即使这个例子看起来很愚蠢,我真的需要在我的实际应用程序中对有符号/无符号和32/64位整数重载f()
,并且它们的行为必须取决于我正在播放时整数的大小有点。我该怎么办?
答案 0 :(得分:1)
简单回答:不要使用f
致电std::size_t
- 请使用f
接受的确切类型之一进行调用。
替代答案:您只关心签名和位数。将std::enable_if
与所有可能的组合一起使用:
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";
}