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)