Tav*_*nes 13 c++ conversion-operator language-lawyer overload-resolution copy-initialization
我有一些代码如下:
class bar;
class foo
{
public:
operator bar() const;
};
class bar
{
public:
bar(const foo& foo);
};
void baz() {
foo f;
bar b = f; // [1]
const foo f2;
bar b2 = f2; // [2]
}
Run Code Online (Sandbox Code Playgroud)
GCC在[2]处给出错误,但不是[1].Clang给出了两个错误,显然MSVC都没有给出错误.谁是对的?
模糊的。(另外,如果您停在 tl;dr 处,那么该language-lawyer标签可能不适合您。^_^)
两个候选者都有一个const foo&参数,它同等地绑定到const fooorfoo参数。没有出现其他更喜欢其中一种功能的规则。
根据当前的 C++ 工作草案进行分解
在这两种情况下
T是正在初始化的类型,在这两种情况下都是bar.
S是初始化表达式的类型,在两种情况下分别是foo和const foo。
T候选者的转换构造函数( [over.match.copy]/1.1 )
bar::bar(const foo& foo);是候选人_cv_ S这样的,因此考虑非显式转换函数:( [over.match.copy]/1.2 )
foo::operator bar() const不隐藏在foo或 之内const foo,并且产生bar与 相同的结果T,因此是候选者。所以我们的候选列表在这两种情况下是相同的:
bar::bar(const foo& foo)foo::operator bar() const在这两种情况下,我们都有一个用户定义的转换,其中包括:
如果我们选择构造函数,“结果类型”是“目标类型的 cv 未限定版本的纯右值,其结果对象由构造函数初始化”( [dcl.init]/17.6.3 ),因此对于两个候选函数中,第二个标准转换是Identity ( bar-> bar)。
根据[dcl.init]/17.6.3foo ,在两种情况下,初始化表达式将分别成为所选调用的参数const foo。
bar::bar(const foo& foo)foo存在从和const foo到const foo&( [over.match.viable]/4 )的隐式转换序列const foo与两者引用兼容foo,并且const fooasconst比两者都更符合简历资格const。[dcl.init.ref]/4const foo&直接绑定到左值foo和左值const foo。[dcl.init.ref]/5foo::operator bar() constconst foo&在这两种情况下都是([over.match.funcs]/4)foo存在从和const foo到const foo&( [over.match.viable]/4 )的隐式转换序列两者都是Identity => User Defined Conversion => Identity,即都是用户定义的转换序列。
我们可以在序列之间建立一个排名吗?仅当以下情况之一适用时
转换序列是无法区分的,即没有更好也没有更差
这两个函数是“更好”的函数吗?仅当以下情况之一适用时
bar,但另一个不是bar( [over.match.best]/1.9 )的基类的构造函数两者都不是“更好”的函数,因此调用格式不正确。[超过匹配最佳]/2