8

你能告诉我为什么下面的代码给了我以下错误 -重载“C(int)”的调用是模棱两可的

我认为由于 C(char x) 是私有的,因此只有 C(float) ctor 从外部可见,应该通过将 int 转换为 float 来调用它。

但事实并非如此。

class C
{
    C(char  x)
    {
    }
public:
    C(float t)
    {
    }
};

int main()
{
    C p(0);
}
4

3 回答 3

19

Scott Meyer 在“Effective C++”中对此进行了讨论。这是模棱两可的原因是他们想确保仅仅改变成员的可见性不会改变其他地方已经存在的代码的含义。

否则,假设您的 C 类位于某个标题中。如果您有一个私有的 C(int) 成员,那么您提供的代码将调用 C(float)。如果由于某种原因 C(int) 成员被公开,旧代码会突然调用该成员,即使旧代码和它调用的函数都没有改变

编辑:更多原因:

更糟糕的是,假设您有以下 2 个功能:

C A::foo() 
{
    return C(1.0);
}

C B::bar() 
{
    return C(1.0);
}

这两个函数可以调用不同的函数,具体取决于 foo 或 bar 是否被声明为 C 的友元,或者 A 或 B 是否继承自 C。相同的代码调用不同的函数是可怕的。

(这可能不如 Scott Meyer 的讨论那么好,但这就是想法。)

于 2009-03-13T20:18:38.457 回答
7

0 是一种int类型。因为它可以同等地隐式转换为 float 或 char,所以调用是不明确的。可见性与这些目的无关。

要么 put 0.0, 0., or 0.0f, 要么完全摆脱C(char)构造函数。

编辑:标准的相关部分,第 13.3 节:

3) [...] 但是,一旦确定了候选函数和参数列表,最佳函数的选择在所有情况下都是相同的:

  • 首先,候选函数的一个子集——那些具有适当数量的参数并满足某些其他条件的函数——被选择来形成一组可行的函数(13.3.2)。
  • 然后根据将每个参数与每个可行函数的相应参数匹配所需的隐式转换序列 (13.3.3.1) 选择最佳可行函数。

4) 如果存在最佳可行函数并且是唯一的,则重载决议成功并产生它作为结果。否则重载解析失败并且调用格式错误。当重载决议成功,并且最佳可行函数在使用它的上下文中不可访问(第 11 条)时,程序是非良构的。

请注意,可见性不是选择过程的一部分。

于 2009-03-13T20:18:41.720 回答
-1

我不这么认为:

C p(0);

正在转换为:

C(float t)

你可能需要做:

C p(0.0f);
于 2009-03-13T20:19:39.533 回答