**注意:**这与Determine number of bits in integral type at compile time非常相似,但这是一个非常简化的版本,所有内容都包含在一个.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
4条答案
按热度按时间pbgvytdp1#
格雷格一针见血:
int32_t
和int64_t
是typedef,可能是也可能不是long
。如果两者都不是long
的typedef,重载解析可能失败。long->int32_t
和long->int64_t
均具有秩=提升(表12,13.3.3.1.2)zbdgwd5y2#
代码是否可以编译是由实现定义的。没有类型
int32_t
或int64_t
;这些只是现有整型的typedef。如果类型恰好是一个已经重载的类型(int
,long
或long long
),这几乎是肯定的,那么你有同一个函数的多个定义。如果它们在同一个翻译单元中,则是编译时错误,需要进行诊断。如果它们在不同的翻译单元中,这是未定义的行为,但我想大多数实现也会生成错误。在您的情况下,最好的解决方案可能是将
msg
作为模板,并将类型的名称作为参数传递。vltsax253#
| 免责声明|
| --|
| 这个解决方案最初是由作者在他们的问题中发布的。|
解决方案是提供一个函数,成功地将
int
,long
和long long
Map到适当的int32_t
或int64_t
。这可以在运行时通过if (sizeof(int)==sizeof(int32_t))
类型语句简单地完成,但编译时解决方案更可取。通过使用boost::enable_if
可以获得编译时解决方案。以下代码适用于MSVC 10和gcc 4.6.3。可以通过禁用非整数类型来进一步增强解决方案,但这超出了此问题的范围。
ogsagwnx4#
正如在其他答案中提到的,模板参数推导在这种情况下可以提供帮助,但它不足以消除
<cstdint>
中定义的所有可能的typedef之间的歧义。Demo