C++ 重载函数的调用不明确

C++ 重载函数的调用不明确,c++,compiler-errors,C++,Compiler Errors,这个错误消息是什么意思 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*) 我的代码如下所示: #include <iostream> #define BYTES 8

这个错误消息是什么意思

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*)
我的代码如下所示:

#include <iostream>
#define BYTES 8
using namespace std ;

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

void huge::setval(unsigned int t) {
    for(int i = 0; i< BYTES ; i++) {
        data[i] = t;
        t = t >> 1;
    }
}

void huge::setval(const char *s) {
    for(int i = 0; i< BYTES ; i++)
        data[i] = s[i];
}

int main() {
    huge p;
    p.setval(0);
    return 0;
}
#包括
#定义字节8
使用名称空间std;
班级人数巨大{
私人:
无符号字符数据[字节];
公众:
void setval(无符号整数);
void setval(const char*);
};
void巨型::setval(unsigned int t){
for(int i=0;i>1;
}
}
void巨型::setval(常量字符*s){
for(int i=0;i
使用

p.setval(静态_cast(0));

p.setval(静态_cast(0));

如错误所示,
0
的类型为
int
。这可以很容易地转换为
无符号int
常量char*
。通过手动进行强制转换,您可以告诉编译器需要哪个重载。

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

p.setval(static_cast<const char *>( 0 ));
p.setval(静态_cast(0));
请注意,在编译代码后,代码中存在分段错误(取决于您真正想要调用的函数)。

替换
p.setval(0)使用以下代码

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

这样它就可以确定常量0是哪种类型。

这是不明确的,因为指针只是一个地址,所以
int
也可以被视为指针–0(一个
int
)可以同样容易地转换为
无符号int
char*

简单的回答是调用
p.setval()
,使用它实现的类型之一:
unsigned int
char*
p.setval(0U)
p.setval((unsigned int)0)
p.setval((char*)0)
都将编译


一般来说,首先不要脱离这种情况,不要定义具有类似类型的重载函数。

< P>文字>代码> 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*);
};
class庞大
{
私人:
无符号字符数据[字节];
公众:
void setval(无符号整数);
模板void setval(const T*);//未实现
模板void setval(const char*);
};

如果我们考虑常数值的类型,它应该是非常简单的,它应该是“无符号int”而不是“int”。< /P> 而不是:

setval(0)
使用:


后缀“u”告诉编译器这是一个无符号整数。然后,不需要进行转换,调用将是明确的。

我想这个问题的答案将取决于您尝试调用的函数的版本。我可以假设,但很明显,除非你告诉我,否则我不能肯定。我想知道,这是否适用于编译器…@KonradRudolph字面
0
对于
无符号int
常量char*
@RyanP都是有效的值是的,我一般都知道。不知道我当时的意思。等不及C++0x了,我们终于有了nullptr关键字:)p.setval((char*)0)将编译,但应用程序崩溃了。p、 setval(0U)工作得很好,但我必须在类声明之外包含专门化。基本上包括
template::setval(const char*)就在类声明的下方。如果没有,我会收到一个关于在类作用域中专门化模板的错误。虽然这是个大把戏,但在我的一些接口之前,这让我很难堪。<代码> 0 <代码>在C++中只有一个意思。它是类型为
int
的整数文本。如果OP确实有一个重载采用
int
,另一个重载采用
char*
,则重载解析将成功并选择
int
重载。但是,OP使用
unsigned int
作为参数类型。这两种转换,
int
->
unsigned int
vs null pointer constant->
char*
是不明确的。@dyp:如果
0
只有一种含义,它怎么会涉及到两种不同起始类型的不明确转换呢?我不太明白“起始类型”是什么意思。
0
的类型是
int
int
可以转换为
无符号int
。计算结果为
0
int
类型的常量表达式也可以转换为任何指针类型。例如,g++和clang++接受
1-1
作为有效的空指针常量(尽管clang++仅在C++03模式下)。也就是说,
0
不是特别的,它只是满足了启用这两个独立转换的条件。如果我强制转换,它仍然抱怨它不明确,该怎么办?我有一个带构造函数的结构声明,它声称构造函数和实际的
struct Thing{
line之间存在歧义?最好的答案,告诉编译器的简单而优雅的方式
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*);
};
setval(0)
setval(0u)