2011-01-12 65 views
16

这个错误信息是什么意思?重载函数调用不明确

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; 
} 
+4

我想这个问题的答案将取决于你试图调用哪个版本的函数。我可以假设,但显然我不能肯定,除非你告诉我。这将与编译器一起工作,我想知道...... – 2011-01-12 17:59:25

+0

@KonradRudolph字面值`0`是`unsigned int`和`const char *`的有效值。 – 2017-03-23 22:47:47

+0

@RyanP是的,我通常意识到。不知道我当时的意思。 – 2017-03-23 22:51:06

回答

17

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

由于您的setval函数可以接受intchar*,因此编译器无法确定您的意思。

最简单的解决方案是将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*); 
}; 
1

使用

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

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

正如错误指示的0类型是int。这可以简单地转换为unsigned intconst char *。通过手动进行投射,您可以告诉编译器您想要的超载。

1

演员的值,因此编译器知道调用哪个函数:

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

注意,你已经在你的代码分段错误,你得到它的编译(取决于后哪些功能你真的想叫)。

3

用以下替换p.setval(0);

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

这样它就知道常数0是哪种类型。

2

这是不明确的,因为指针只是一个地址,所以一个int也可以被当作一个指针 - 0(一个int)可以很容易地转换为unsigned int或char *。

简而言之,就是调用p.setval(),其中明确指定了实现的类型之一:unsigned int或char *。 p.setval(0U),p.setval((unsigned int)0)和p.setval((char *)0)将全部编译。

尽管不要在这种情况下摆脱这种情况,但通过不使用类似类型定义重载函数通常是一个好主意。

+0

对于最后一段尤其如此。 – 2011-01-12 18:04:04

12

的解决方案是很简单的,如果我们考虑在恒定值的类型,这应该是“无符号int“而不是”int“。

相反的:

setval(0) 

用途:

setval(0u) 

后缀 “U” 告诉编译器,这是一个无符号整数。然后,不需要转换,呼叫将是明确的。