传递 long 时 int32_t 或 int64_t 参数之间的不明确重载

问题描述 投票:0回答:2

注意:这与在编译时确定整数类型的位数非常相似,但是这是一个非常简化的版本,全部包含在一个

.cpp

编辑:添加了一个解决方案 - 尽管给出了(并接受)正确的解释,但我找到了一种通用解决问题的方法。

问题

问题在于

之类的函数
 msg(int32_t);
 msg(int64_t);

类似的电话

long long myLong = 6;
msg(myLong);    // Won't compile on gcc (4.6.3), call is ambiguous

这在 MSVC 上编译。任何人都可以解释为什么这在 gcc 上失败(我假设这可能与 gcc 通常严格符合标准有关)以及如何正确实现相同效果的示例?

#include <iostream>
#include <stdint.h>

#include <boost/integer.hpp>

using namespace std;

void msg(int v) { cout << "int: " << sizeof(int) << ' ' << v << '\n'; }
void msg(long v) { cout << "long: " << sizeof(long) << ' ' << v << '\n'; }
void msg(long long v) { cout << "long long: " << sizeof(long long) << ' ' << v << '\n'; }

void msg2(int32_t v) { cout << "int32_t: " << sizeof(int32_t) << ' ' << v << '\n'; }
void msg2(int64_t v) { cout << "int64_t: " << sizeof(int64_t) << ' ' << v << '\n'; }
void msg2(uint32_t v) { cout << "uint32_t: " << sizeof(uint32_t) << ' ' << v << '\n'; }
void msg2(uint64_t v) { cout << "uint64_t: " << sizeof(uint64_t) << ' ' << v << '\n'; }


int main()
{
 
    int myInt = -5;
    long myLong = -6L;
    long long myLongLong = -7LL;

    unsigned int myUInt = 5;
    unsigned int myULong = 6L;
    unsigned long long myULongLong = 7LL;

    msg(myInt);
    msg(myLong);
    msg(myLongLong);

    msg2(myInt);
    msg2(myLong);     // fails on gcc 4.6.3 (32 bit)
    msg2(myLongLong);
  
    msg2(myUInt);
    msg2(myULong);   // fails on gcc 4.6.3 (32 bit)
    msg2(myULongLong);

   return 0;
}
// Output from MSVC  (and gcc if you omit lines that would be commented out)
int: 4 5
long: 4 6
long long: 8 7
int32_t: 4 -5
int32_t: 4 -6   // omitted on gcc
int64_t: 8 -7
uint32_t: 4 5
uint32_t: 4 6   // omitted on gcc
uint64_t: 8 7
c++ gcc overload-resolution
2个回答
3
投票

Greg 一语中的:

int32_t
int64_t
是类型定义,可能是也可能不是
long
。如果两者都不是
long
的 typedef,重载解析可能会失败。
long->int32_t
long->int64_t
都有 Rank=Promotion(表 12, 13.3.3.1.2)


3
投票

代码是否可以编译是由实现定义的。没有类型

int32_t
也没有
int64_t
;这些只是现有整型的 typedef。如果该类型恰好是已经重载的类型(
int
long
long long
)(几乎可以肯定是这种情况),那么同一个函数就有多个定义。如果它们位于同一翻译单元中,则这是编译时错误,需要诊断。如果它们位于不同的翻译单元中,则这是未定义的行为,但我想大多数实现也会生成错误。

在您的情况下,最好的解决方案可能是制作

msg
模板,并将类型名称作为参数传递。

© www.soinside.com 2019 - 2024. All rights reserved.