【问题标题】:How do I fix an "ambiguous" function call?如何修复“模棱两可”的函数调用?
【发布时间】:2011-11-24 21:06:05
【问题描述】:

我正在编写一个用于类的 C++ 程序,而我的编译器正在抱怨“模棱两可”的函数调用。我怀疑这是因为有几个函数定义了不同的参数。

如何告诉编译器我想要哪一个?除了针对特定情况的修复之外,是否有一般规则(例如类型转换)可以解决这类问题?

编辑:

就我而言,我尝试在cout 语句中调用abs(),并传入两个doubles。

cout << "Amount is:" << abs(amountOrdered-amountPaid);

编辑2:

我包括这三个标题:

#include <iostream>
#include <fstream>
#include <iomanip>

using namespace std;

编辑3:

我已经完成了没有这段代码的程序,但是为了解决这个问题,我已经重现了这个问题。逐字错误是:

对“abs”的调用不明确。

编译器提供了三个版本的abs,每个版本都采用不同的数据类型作为参数。

【问题讨论】:

  • 能否请您从您的代码中展示一个示例?
  • 这真的取决于情况。您需要发布代码,并且如果编译器错误包括哪些函数是候选函数(最近的 GCC 有),这也会有所帮助。
  • 包含哪些标题也很好。
  • 您遇到的逐字错误是什么?
  • @Moshe:也许你可以包含其余的信息。您说“编译器提供了三个版本的abs”,但您没有显示这些消息是什么。

标签: c++ ambiguous-call


【解决方案1】:

不知道为什么这不调用 abs 的 int 版本,但您可以尝试将表达式 (amountOrdered - amountPaid) 类型转换为 int 即

cout <<"Amount is: "<< abs( (int)(amountOrdered - amountPaint) );

【讨论】:

  • “不知道为什么这不调用 abs 的 int 版本”可能是因为 amountOrderedamountPaid 是双打的吗?
  • 你是对的,不知道我在想什么! @OP 编译器对调用哪个版本(long 或 double)感到困惑,因为它不确定是否需要从 double 类型转换为 long 或 int。 .R.Martinho 先生 - 我想我的解决方案将帮助编译器决定调用哪个版本。所以我有点正确:)
【解决方案2】:

发生的情况是,您已将&lt;cstdlib&gt; 包含在using namespace std; 中(间接地,因为它已被iostream 包含在内)和using namespace std;。这个头文件在std 中声明了两个函数,名称为abs()。一个接收并返回long long,另一个返回long。另外,在全局命名空间(返回int)中有一个来自&lt;stdlib.h&gt;

修复:好吧,接受 double 的 abs()&lt;cmath&gt; 中,这实际上会给你想要的答案!

【讨论】:

  • TL;DR:避免using namespace
  • @MatthieuM.,即使在 iOS SDK 中使用std::abs(),我也看到了这个(语义)错误。当我删除 std:: 并仅使用 abs() 时,该错误被删除。
  • 是的,问题更多是由于自动数字类型转换。
【解决方案3】:

&lt;cstdlib&gt; 包含的 abs 函数为 intlonglong long 重载。由于您将double 作为参数,编译器没有完全匹配,因此它尝试将double 转换为abs 接受的类型,但它不知道是否应该尝试转换它到intlonglong long,因此它是模棱两可的。

但您可能真的想要abs,它接受double 并返回double。为此,您需要包含&lt;cmath&gt;。由于double 参数完全匹配,编译器不会报错。

似乎&lt;cstdlib&gt; 在您包含不应发生的其他标头时自动包含在内。编译器应该给出error: ‘abs’ was not declared in this scope 或类似的东西。

【讨论】:

  • abs 不是函数模板。给出模板参数是行不通的。 static_cast&lt;foo&gt;(bar) 会编译(但仍然给出错误答案)
  • @mkb - 谢谢,我忘了它们只是重载而不是模板函数专业化。编辑了那部分。
【解决方案4】:

尝试使用&lt;cmath&gt; 中定义的fabs。它将floatdoublelong double 作为参数。 abs 定义在 &lt;cmath&gt;&lt;cstdlib&gt; 中。区别在于abs(int)abs(long)abs(long long)&lt;cstdlib&gt;中定义,而其他版本在&lt;cmath&gt;中定义。

【讨论】:

  • 解决此类错误的常见解决方案是使用 C++ 版本的库而不是标准 C 库,例如:cstdio 代替 stdio.h。 C++ 库的名称带有前缀 'c' 而没有 '.h'
猜你喜欢
  • 2019-08-19
  • 1970-01-01
  • 1970-01-01
  • 2017-05-15
  • 2014-10-21
  • 1970-01-01
  • 1970-01-01
  • 2016-01-19
  • 1970-01-01
相关资源
最近更新 更多