【问题标题】:Ambiguous Overloaded Functions - How and Why?模棱两可的重载函数——如何以及为什么?
【发布时间】:2012-04-06 03:02:44
【问题描述】:

我很难弄清楚是什么导致某些函数调用模棱两可,而另一些则很好。我的 BitPacker 对象中有以下重载函数调用:

static __declspec(dllexport) void PackBits(void *dstBuffer, unsigned long long data, unsigned int &offsetBits, const unsigned int numBits);
static __declspec(dllexport) void PackBits(void *dstBuffer, bool data, unsigned int &offsetBits, const unsigned int numBits);
static __declspec(dllexport) void PackBits(void *dstBuffer, float data, unsigned int &offsetBits, const unsigned int numBits);
static __declspec(dllexport) void PackBits(void *dstBuffer, double data, unsigned int &offsetBits, const unsigned int numBits);

我正在尝试从另一个包含“BitPacker.h”的对象中进行以下调用:

void Date::ReflectToBitBuffer(void)
{
    unsigned int offsetBits = 0;
    BitPacker::PackBits(m_packedBuffer, m_year, offsetBits, YR_BITS);
    BitPacker::PackBits(m_packedBuffer, m_month, offsetBits, MO_BITS);
    BitPacker::PackBits(m_packedBuffer, m_day, offsetBits, DY_BITS);
}

"m_year"、m_month" 和 "m_day" 是 int 成员变量。但是尝试编译时出现以下错误:

error C2668: 'BitPacker::PackBits' : ambiguous call to overloaded function
could be 'void BitPacker::PackBits(void *,double,unsigned int &,const unsigned int)'
or 'void BitPacker::PackBits(void *,float,unsigned int &,const unsigned int)'
or 'void BitPacker::PackBits(void *,bool,unsigned int &,const unsigned int)'
or 'void BitPacker::PackBits(void *,unsigned __int64,unsigned int &,const unsigned int)'
while trying to match the argument list '(char *, int, unsigned int, )'

所以我用以下 main.cpp 编写了一个测试解决方案来测试重载,我在下面的编译很好:

void OverloadTest(float f);
void OverloadTest(int n, int &numbits);
void OverloadTest(double d);
void OverloadTest(char c, int &numbits);
void OverloadTest(long long l, int &numbits);
void OverloadTest(long long *l);
void OverloadTest(bool b);

int main(int argc, int *argv)
{
    int myInt = 77;
    bool myBool = true;
    float myFloat = 3.14159f;
    double myDouble = 1.57;
    long long myLongLong = 12345;
    long long *ptrLongLong = NULL;
    char myChar = 'q';
    int myNumBits = 10;

    OverloadTest(myInt, myNumBits);
    OverloadTest(myFloat);
    OverloadTest(myDouble);
    OverloadTest(myLongLong, myNumBits);
    OverloadTest(ptrLongLong);
    OverloadTest(myChar, myNumBits);
    OverloadTest(myBool);

    return 0;
}

void OverloadTest(float _f) { int x = 0; }
void OverloadTest(int _n, int &_numbits) { int x = 0; }
void OverloadTest(double _d) { int x = 0; }
void OverloadTest(char _c, int &_numbits) { int x = 0; }
void OverloadTest(long long _l, int &_numbits) { int x = 0; }
void OverloadTest(long long *_l) { int x = 0; }
void OverloadTest(bool b) { int x = 0; }

我什至试图简化:

void Date::ReflectToBitBuffer(void)
{
    unsigned int offsetBits = 0;
    unsigned int testVar2 = 12;
    unsigned int testVar1 = 1977;

    BitPacker::PackBits(m_packedBuffer, testVar1, offsetBits, testVar2);
}

我仍然有歧义。如果我使用浮点数,但我不会。目前我完全困惑为什么我的测试场景不会产生这个错误。任何人都可以阐明问题是什么,因为在我看来,第一个代码示例中的函数原型签名有足够的不同,可以编译。

【问题讨论】:

  • 我没有看到将 int 作为第二个参数的 PackBits 函数,这似乎正是错误消息告诉您的内容。 int 必须转换为另一种类型,但编译器不知道您想要的类型。
  • 在您的测试场景中传递unsigned int

标签: c++ overloading ambiguity


【解决方案1】:

看起来“int”可以转换为所有 4 种类型的重载函数,但没有一个与您的调用完全匹配。也许这就是问题所在。 尝试使您的调用与函数定义完全匹配,或者为您的调用制作一个 int 版本?

【讨论】:

  • C 调用约定不区分有符号和无符号类型,或者只是给出我理解的警告。但是,是的,我确实尝试过使用 unsigned int 和 int。我的日期类的所有成员实际上都是 int 的,当它不起作用时,我尝试了 unsigned int。
  • 其实原型是一个无符号长长。我曾认为将 unsigned int 传递给一个采用 unsigned long long 的函数会自动向上转换它吗?我尝试了 unsigned long long 并且它有效。谢谢大家。
  • 看来我的根本问题是静态函数的参数比非静态函数更“严格”?静态函数似乎能够区分有符号和无符号类型...
  • 我假设您在谈论 OverloadTest 函数与 PackBits 函数?静态与为什么一个工作而另一个不工作没有任何关系。所有的 OverloadTest 调用都是完全匹配的,而 PackBits 问题是因为没有完全匹配,也没有比任何其他可能的隐式转换更好的单个隐式转换。
  • 啊,我想我现在明白了。因此,如果我只有 1 个采用“int”的函数,它将同时接受“int”或“unsigned int”,除非我创建了两个同时采用两者的函数。我想这就是我感到困惑的地方。感谢您的帮助!
猜你喜欢
  • 2012-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-02
相关资源
最近更新 更多