为何更优标准转换序列加用户自定义转换不能使重载更优?
为何调用f(1)会出现重载函数调用模糊错误?
先看给出的代码:
template <class T> struct wrapper { wrapper(const T&); }; void f(wrapper<int>); void f(wrapper<double>); int main () { f(1); // error: ambiguous call to overloaded function }
当调用f(1)时,编译器需要在两个重载的f函数中做选择,对应的两条转换路径分别是:
- 匹配
f(wrapper<int>):1(int类型)→const int&(通过限定转换和引用绑定的精确匹配)→ 调用wrapper<int>的构造函数完成用户定义转换。 - 匹配
f(wrapper<double>):1→double(浮点转换)→const double&(临时物化、限定转换和引用绑定)→ 调用wrapper<double>的构造函数完成用户定义转换。
看似第一条路径更优,但编译器判定模糊的核心原因在于:
这两条路径都属于用户定义转换序列(依赖自定义构造函数完成实参到参数类型的转换)。根据C++重载决议规则,当两个用户定义转换序列依赖的是不同的构造函数/转换函数时(这里是wrapper<int>和wrapper<double>各自独立的构造函数),即便前置的标准转换序列有优劣之分,编译器也无法将其中一条路径判定为“更优”——因为这两个构造函数属于完全独立的类型转换逻辑,没有规则能优先选择其中一个来处理int类型的实参。
只有当两个用户定义转换序列复用同一个构造函数/转换函数(比如同一模板构造函数的不同特化)时,编译器才会通过比较前置标准转换序列的优劣来筛选重载。而本例中两个构造函数分属不同的wrapper特化,无法区分优先级,最终导致重载模糊。
内容的提问来源于stack exchange,提问作者Jan Schultke
相关产品推荐
相关产品推荐

