传递整数文字 0 时,调用采用 unsigned int 或指针的重载函数是不明确的

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

这个错误信息是什么意思?

error: call of overloaded ‘setval(int)’ is ambiguous
huge.cpp:18: note: candidates are: void huge::setval(unsigned int)
huge.cpp:28: note:                 void huge::setval(const char*)

我的代码如下所示:

class huge {
private:
    unsigned char data[8];
public:
    void setval(unsigned int) { /* .... */ }
    void setval(const char *) { /* ... */ }
};

int main() {
    huge p;
    p.setval(0);
}
c++ compiler-errors overloading overload-resolution
6个回答
32
投票

字面量

0
在 C++ 中有两种含义。
一方面,它是一个值为 0 的整数。
另一方面,它是一个空指针常量。

由于您的

setval
函数可以接受
int
char*
,编译器无法决定您指的是哪个重载。

最简单的解决方案是将

0
转换为正确的类型。
另一种选择是确保首选
int
重载,例如将另一个作为模板:

class huge
{
 private:
  unsigned char data[BYTES];
 public:
  void setval(unsigned int);
  template <class T> void setval(const T *); // not implemented
  template <> void setval(const char*);
};

18
投票

如果我们考虑常量值的类型,解决方案非常简单,应该是“unsigned int”而不是“int”。

代替:

setval(0)

用途:

setval(0u)

后缀“u”告诉编译器这是一个无符号整数。那么,就不需要任何转换,并且调用将是明确的。


3
投票

p.setval(0);
替换为以下内容。

const unsigned int param = 0;
p.setval(param);

这样它就可以确定常量 0 是什么类型。


1
投票

使用

p.setval(static_cast<const char *>(0));

p.setval(static_cast<unsigned int>(0));

如错误所示,

0
的类型是
int
。这可以很容易地转换为
unsigned int
const char *
。通过手动进行转换,您可以告诉编译器您想要哪个重载。


1
投票

转换该值,以便编译器知道要调用哪个函数:

p.setval(static_cast<const char *>( 0 ));

请注意,在编译代码后,您的代码中存在分段错误(取决于您真正想要调用的函数)。


1
投票

这是不明确的,因为指针只是一个地址,因此

int
也可以被视为指针 - 0(
int
)可以同样轻松地转换为
unsigned int
char *

简短的答案是用明确是其实现类型之一的东西来调用

p.setval()
unsigned int
char *
p.setval(0U)
p.setval((unsigned int)0)
p.setval((char *)0)
都将编译。

不过,通过不定义具有此类相似类型的重载函数,通常最好避免出现这种情况。

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