考虑以下代码(摘自https://en.cppreference.com/w/cpp/language/cast_operator)
struct To {
To() = default;
To(const struct From&) {} // converting constructor
};
struct From {
operator To() const {return To();} // conversion function
};
int main()
{
From f;
To t2 = f; // copy-initialization: ambiguous
// (note, if conversion function is from a non-const type, e.g.
// From::operator To();, it will be selected instead of the ctor in this case)
}
正如评论所说,由于存在两个候选(转换函数和转换构造函数同等适用),因此以下行确实是模棱两可的
To t2 = f; //compile error
但是,如注释中所述,如果我从const
函数中删除了conversion
,则会导致以下代码:
struct From {
operator To() {return To();} // conversion function
};
该调用编译良好。
const
限定符不应影响conversion
函数的返回值,那么为什么调用不再是模棱两可的?
答案 0 :(得分:3)
const限定符不应影响转换函数的返回值,那么为什么调用不再是模棱两可的?
它不会影响结果,但是会影响选择最佳可行方法的重载分辨率。类似于这些组合函数的情况
To make(From const&);
To make(From&);
在make(f)
中哪个过载是更好的匹配?这是第二个,因为参数类型为非常量,可以更好地匹配非常量本身的参数(f
)。
答案 1 :(得分:1)
const限定符不应影响转换函数的返回值
这并没有真正影响,但这也不相关。
它确实影响的是参数-这是对this
的隐式引用。对于const成员函数,隐式参数是const左值;对于非const成员函数,隐式参数是非const。这些参数是影响过载解析的因素。
在原始代码中,构造函数和转换运算符的参数完全相同,因此从任何类型到任意一个参数的转换顺序都是同等可取的,因此模棱两可。
没有const,您的非const左值表达式f
不需要任何转换,而构造函数则需要转换为const左值。这样,操作员是过载解决方案的首选。如果您写过const From f;
,则将选择参数为const的构造函数,因为在这种情况下,非const转换运算符甚至都不是有效的候选对象。