删除重载功能。 C ++ 11。超载的召唤......含糊不清

时间:2017-12-28 17:34:40

标签: c++ c++11

有全局功能(仅举例):

void func( int i )
{
    std::cout << i + 100 << std::endl;
}

我假设用char参数调用这个函数没有任何意义所以我使用delete:

void func(char) = delete;

所以我希望以下呼叫应该是可能的:

func(1);
func(3.1);
func(true);

用char参数调用应该是forbiden:

func('a');

但事实并非如此。致电func('a')时,我得到了预期的结果:

error: use of deleted function ‘void func(char)’

但在致电func(2.3)期间,我得到了:

error: call of overloaded ‘func(double)’ is ambiguous

为什么会出现此错误?没有删除带有char参数的函数,double被转换为int并调用了func(int),为什么现在它被禁止?

3 个答案:

答案 0 :(得分:12)

致电时

func(2.3)

您将double传递给该函数。候选人列表包含 func(int)func(char),因为重载解决方案发生before delete kicks in

  

如果函数重载,首先会发生重载决策,如果选择了删除的函数,程序只会格式错误 Ref:cppreference.com,请参阅{{3} }用于精确的标准报价。

现在double可以转换为charint,因此含糊不清。

  

没有删除带有char参数的函数,double被转换为int并调用了func(int),为什么现在它被禁止?

即使没有delete char版本,您也会收到歧义错误,请参阅直播Avishai's answer。当然,如果您只定义func(int),那么就不会有歧义,因此double很乐意转换为int

答案 1 :(得分:1)

每次为函数参数传入非完全匹配时,都必须进行转换。当您有两个函数时,无论是否删除了一个函数,它们仍然参与重载解析。编译器选择最佳匹配,然后生成对它的调用,或者如果函数不可访问或删除则失败。

为了使重载分辨率起作用,它会使一组候选函数看到哪个具有到参数集的最短转换路径。就规则而言,所有内置数字类型都是“相等”的转换。因此,如果你使用2.5调用,这是一个double,它必须转换并且可以转换为char或者转换为具有相同排名的int,因此调用是不明确的。

答案 2 :(得分:0)

它仍然不明确,因为编译器在检查已删除的函数之前尝试解决重载。参见:

§8.4.3删除定义

  

除了声明它之外,隐式或显式引用已删除函数的程序是不正确的。   [   注意:   这包括隐式或显式调用函数并形成指向成员的指针或指针   到功能。它甚至适用于未进行潜在评估的表达式中的引用。如果一个功能   重载,只有在通过重载决策选择函数时才会引用它。    - 结束说明   ]

§13.3.3.1隐式转换序列:

  

隐式转换序列仅涉及类型,cv资格和值类别   参数以及如何转换它们以匹配参数的相应属性。其他   属性,例如生命周期,存储类,对齐方式,参数的可访问性,是否参数   是一个位字段,是否删除了一个函数(8.4.3),将被忽略。所以,虽然是隐式转换   可以为给定的参数 - 参数对定义序列,从参数到参数的转换   在最终分析中,参数可能仍然不正确。