为什么下面这段带有非常量转换函数的代码没有歧义呢?

Why the following code with non-const conversion function is not ambiguous?

考虑以下代码(摘自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

但是,如注释所述,如果我从 conversion 函数中删除 const 会导致以下代码:

struct From {
    operator To() {return To();} // conversion function
};

调用编译正常。
const 限定符不应该影响 conversion 函数 return 值,那么为什么调用不再有歧义?

The const qualifier should not affect the conversion function return value, so why the call is no longer ambiguous?

它不会影响结果,但会影响选择最佳可行方法的重载决策。类似于这些组合函数的情况

To make(From const&);
To make(From&);

make(f)哪个重载更匹配?这是第二个,因为参数类型是非常量,更好地匹配参数 (f),它本身是非常量。

The const qualifier should not affect the conversion function return value

确实没有影响,但这也不相关。

它影响的是参数 - 这是对 this 的隐式引用。隐式参数是 const 成员函数的 const 左值和非 const 成员函数的非常量。参数是影响重载决议的因素。

在原始代码中,构造函数和转换运算符参数完全相同,因此从任何类型到任何一个参数的转换序列都同样可取,因此不明确。

如果没有 const,您的非 const 左值表达式 f 不需要任何转换,而构造函数确实需要转换为 const 左值。因此,运算符是重载决议的首选。如果您编写了 const From f;,那么将选择参数为 const 的构造函数,因为在这种情况下,非常量转换运算符甚至都不是有效的候选者。