2012-05-06 60 views
0

在C++C++函数过载暧昧

void foo(int i) 
{ std::cout<<"int"<<std::endl; } 

void foo(float i) 
{ std::cout<<"float"<<std::endl; } 

void foo(void *i) 
{ std::cout<<"void *"<<std::endl; } 

void foo(bool b) 
{ std::cout<<"bool"<<std::endl; } 

void main() { foo(0); } 

编译此时,它使错误。
在2008年的视觉工作室,误差为C2668:“功能”:不明确调用重载函数

我知道为什么这个问题会发生,我知道一个解决方案,使用时间类型转换。但我认为这不是一个好的解决方案,因为使用这种方法可以消除函数重载的词法。

在我的项目中,我做了一个词汇对象,将自动类型更改为int,float,std :: basic_string和函数指针。超载所有类型转换运算符和创建者。但是当我输入'NULL'时,会出现错误C2668。

其实它几乎没有问题。唯一严重的问题是使用FALSE时。我的项目是核心库,所以我不能指导每个最终客户端程序员。

谁知道解决这个问题的技巧或提示更聪明的方法?

+0

这个编译好gcc 4.5。 – mfontanini

+0

如果这是你的真实代码,那么报告一个编译器错误 –

回答

0

也许你可以将FALSE定义为((bool)0)而不是0(为什么不使用false代替?!)。

另外,如果你想想看,有f(int *)f(char *),并呼吁f(NULL)暧昧,所以你需要反正投!编译器不会神奇地知道你的意图,除非你告诉它。所以如果某些东西本质上是模棱两可的,那么只需通过强制转换就可以使其明确无误。

+3

在C++中,'#define NULL((void *)0)'是有害的。这意味着你必须在每次使用NULL时添加一个转换。重写标准库的定义似乎是一个非常糟糕的主意。 – delnan

+0

@delnan,你是对的。我从帖子中删除了该部分。 – Shahbaz

+0

好吧,我测试的方式,但我遇到同样的问题。万分感谢。我只是在这个模棱两可中使用'int'。 void *(函数指针)是使其他setter/getter模板函数。我认为这个模棱两可的问题无法避免。 – user1101221

2

就像现在这样,你的代码不应该导致错误 - 没有歧义。当通过0(一个int)时,显然foo(int)(身份转换)比其他任何人都更好(即使0也可以隐式转换为所有其他重载的类型)。

我的猜测是你正在测试的代码与你发布的代码不太一样。例如,如果你做了而不是有过载需要int,我希望有一个关于模糊过载的错误(因为如上所述,有从0到所有其他过载所采用的类型的隐式转换)。我已经确认VC++ 2008按原样接受了代码(VC 2010以及VC11和g ++ 4.7.0的测试版也是如此)。

顺便说一下,我会注意到main应该真的返回int(尽管它几乎肯定与手头上的问题无关)。

+0

您是对的。为了避免这个问题变得太复杂,我只是简化它。我使用vs2008和我重载int,unsigned int,long,unsigned long。因为每个程序员都使用STL,它有时会返回** size_t **或使用** DWORD **的其他程序员。所以我现在只是一个int类型的重载int,忽略了类型转换的编译器警告。 – user1101221

0

C++ 11通过引入一个新的关键字来作为一个可区分的空指针常量来纠正这个问题:nullptr。它的类型为nullptr_t,它可以隐式转换,并且可以与任何指针类型或成员指针类型进行比较。除了bool以外,它不是可以隐式转换的或者可以与整数类型进行比较。