超载的召唤是模棱两可的

时间:2014-12-22 06:09:42

标签: c++ compiler-construction overloading

我正在开发一个编译器项目。当我在GitHub上查看一些代码时,我在编译源代码时遇到了一个问题。错误是:

call of overloaded ‘newast(<anonymous enum>, NULL, _ast*&, NULL)’ is ambiguous

并且相关的功能是_ast* newast(_action, char*, _ast*, _ast*)_ast* newast(_action, int, _ast*, _ast*)

我不知道为什么会有这样的歧义。然后是.y文件中的相关代码。

| IDENTIFIER '(' ')' { $$ = newast(_call, $1, NULL, NULL); }
        | IDENTIFIER '(' expr ')' { $$ = newast(_call, $1, newast(_dummy, NULL, $3, NULL), NULL); }
        | IDENTIFIER '(' expr ',' expr ')' { $$ = newast(_call, $1, newast(_dummy, NULL, $3, $5), NULL); }
        | IDENTIFIER '(' expr ',' expr ',' expr ')' { $$ = newast(_call, $1, newast(_dummy, NULL, $3, $5), newast(_dummy, NULL, $7, NULL)); }

2 个答案:

答案 0 :(得分:3)

两个重载方法之间的唯一区别是char *和int参数。在提供的代码中,大多数方法都使用NULL作为第二个参数调用newast(),这是不明确的。编译器可以隐式地将NULL转换为int或char *,因此它不知道该怎么做。

你需要更明确。传递除NULL之外的其他内容或显式地将NULL转换为其中一种类型。例如:

newast(_action,(char *)NULL,...

答案 1 :(得分:2)

这是C ++ 03中的一个已知问题。求值为零的常量表达式(例如0)既是整数又是指针(更准确地说,是空指针常量)。由于NULL被定义为这样的表达式,因此它也充当整数和指针。

大多数情况下,NULL被定义为0L,这意味着它不完全是一个int,并且在将它传递给期望int的函数时需要转换。将它传递给需要指针的函数时,还需要进行转换。

因此,如果你有一个重载函数接受int或指针,并用NULL参数调用它,两者都不是完全匹配,所以两者都不是首选,并且调用很暧昧。

如果你可以使用C ++ 11,那么首选nullptr优于NULL,因为nullptr 只是指针而不是整数。否则,请使用static_cast<char*>(NULL)。更好的是,使用std::string

要选择其他重载,请使用0。它与int完全匹配,因此int重载优先于char*重载。