函数重载,整数类型和64位系统上的std :: size_t

时间:2017-02-02 14:35:55

标签: c++11 overloading size-t

以下代码在我的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_tstd::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(),并且它们的行为必须取决于我正在播放时整数的大小有点。我该怎么办?

1 个答案:

答案 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";
}

coliru example