|
编译器根据当前范围内的函数声明与函数调用中提供的参数的最佳匹配,来选择要调用的重载函数。 如果找到合适的函数,则调用该函数。 此上下文中的“Suitable”具有下列含义之一:
找到完全匹配项。
已执行不重要的转换。
已执行整型提升。
已存在到所需自变量类型的标准转换。
已存在到所需参数类型的用户定义转换(转换运算符或构造函数)。
已找到省略号所表示的自变量。
编译器为每个自变量创建一组候选函数。 候选函数是这样一种函数,其中的实际自变量可以转换为形式自变量的类型。
为每个自变量生成一组“最佳匹配函数”,并且所选函数是所有集的交集。 如果交集包含多个函数,则重载是不明确的并会生成错误。 对于至少一个参数而言,最终选择的函数始终比组中的所有其他函数更匹配。 如果没有明显的优胜者,函数调用会生成编译器错误。
考虑下面的声明(针对下面的讨论中的标识,将函数标记为 Variant 1、Variant 2 和 Variant 3):
Fraction &Add( Fraction &f, long l ); // Variant 1
Fraction &Add( long l, Fraction &f ); // Variant 2
Fraction &Add( Fraction &f, Fraction &f ); // Variant 3
Fraction F1, F2;
请考虑下列语句:
F1 = Add( F2, 23 );
前面的语句生成两个集:
集 1:其第一个参数的类型为 Fraction 的候选函数 集 2:其第二个参数可转换为类型 int 的候选函数
Variant 1 Variant 1(可使用标准转换将 int 转换为 long)
Variant 3
集 2 中的函数具有从实参类型到形参类型的隐式转换。 其中一个函数将实参类型转换为相应形参类型的“成本”最小。
这两个集的交集为 Variant 1。 不明确的函数调用的示例为:
F1 = Add( 3, 6 );
前面的函数调用生成以下集:
集 1:其第一个参数的类型为 int 的候选函数 集 2:其第二个参数的类型为 int 的候选函数
Variant 2(可使用标准转换将 int 转换为 long) Variant 1(可使用标准转换将 int 转换为 long)
由于这两个集的交集为空,因此编译器会生成错误消息。
对于参数匹配,具有 n 个默认参数的函数被视为 n+1 个单独函数,并且每个函数均具有不同数量的参数。
省略号 (...) 用作通配符;它与任何实参匹配。 如果你未极其谨慎地设计重载函数集,它可能导致产生许多不明确的集。
重载函数的多义性无法确定,直到遇到函数调用。 此时,将为函数调用中的每个自变量生成集,并且可以确定是否存在明确的重载。 这意味着,多义性可能会保留在代码中,直到它们由特定函数调用引发。
|
|