gpt4 book ai didi

c++ - 诸如 `msg(long)` 与候选 `msg(int32_t)` 和 `msg(int64_t)` 等函数的模糊重载

转载 作者:可可西里 更新时间:2023-11-01 18:36:09 27 4
gpt4 key购买 nike

注意:这与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

解决方案

解决方案是提供一个函数,成功地将 intlonglong long 映射到适当的 int32_tint64_t。这可以在运行时通过 if (sizeof(int)==sizeof(int32_t)) 类型语句轻松完成,但编译时解决方案更可取。通过使用 boost::enable_if 可以获得编译时解决方案.

以下适用于 MSVC10 和 gcc 4.6.3。可以通过禁用非整数类型来进一步增强解决方案,但这超出了这个问题的范围。

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

#include <boost/integer.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_signed.hpp>
#include <boost/type_traits/is_unsigned.hpp>

using namespace std;

template <class InputT>
typename boost::enable_if_c<sizeof(InputT)==sizeof(int32_t) && boost::is_signed<InputT>::value,
int32_t>::type ConvertIntegral(InputT z) { return static_cast<int32_t>(z); }

template <class InputT>
typename boost::enable_if_c<sizeof(InputT)==sizeof(int64_t) && boost::is_signed<InputT>::value,
int64_t>::type ConvertIntegral(InputT z) { return static_cast<int64_t>(z); }

template <class InputT>
typename boost::enable_if_c<sizeof(InputT)==sizeof(uint32_t) && boost::is_unsigned<InputT>::value,
uint32_t>::type ConvertIntegral(InputT z) { return static_cast<uint32_t>(z); }

template <class InputT>
typename boost::enable_if_c<sizeof(InputT)==sizeof(uint64_t) && boost::is_unsigned<InputT>::value,
uint64_t>::type ConvertIntegral(InputT z) { return static_cast<uint64_t>(z); }

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(ConvertIntegral(myInt));
msg2(ConvertIntegral(myLong));
msg2(ConvertIntegral(myLongLong));

msg2(ConvertIntegral(myUInt));
msg2(ConvertIntegral(myULong));
msg2(ConvertIntegral(myULongLong));

return 0;
}

最佳答案

Greg 一语中的:int32_tint64_t 是类型定义,可能也可能不长。如果两者都不是 long 的类型定义,重载解析可能会失败。 long->int32_tlong->int64_t都有Rank=Promotion(表12、13.3.3.1.2)

关于c++ - 诸如 `msg(long)` 与候选 `msg(int32_t)` 和 `msg(int64_t)` 等函数的模糊重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10579544/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com