通过用户定义的转换初始化引用



给定此代码:

struct B { };
struct A
{
A(const B&);
};
void g()
{
B a;
const A& b = a;
}

[dcl.init.ref] 中似乎没有适用的措辞可以使其格式良好(具体来说,没有措辞说明当唯一的用户定义的转换是通过转换构造函数构造临时对象时会发生什么(

第一种情况不适用([over.match.ref] 不考虑构造函数(,第二种情况也不适用(同样,[over.match.ref] 不考虑构造函数(,这给我们留下了第三种情况,因为其中一个类型是类类型,AB引用无关。第三种情况说:

如果T1T2是类类型,并且T1T2引用无关,则使用用户定义转换对类型为"cv1 T1"的对象进行复制初始化的规则来考虑用户定义的转换;如果相应的非引用复制初始化格式不正确,则程序格式不正确。然后,调用转换函数的结果(如非引用复制初始化中所述(用于直接初始化引用。对于此直接初始化,不考虑用户定义的转换。

乍一看看起来不错,但是,它只定义了何时为转换选择转换函数的情况,并且没有说明何时选择转换构造函数(此处将适用 [over.match.copy] 的规则(。如果选择了这样的构造函数,则必须由构造函数创建和初始化临时对象,然后绑定到引用,但在适用的子句中没有提到这一点。是缺少措辞,还是我遗漏了什么?

我错过了什么吗?

据我所知,没有

。措辞

[dcl.init.ref]

。用户定义的转换是使用用户定义的转换对类型为"cv1 T1"的对象进行复制初始化的规则来考虑的,否则将明确允许构造([dcl.init],[over.match.copy],[over.match.conv](...

本身显然允许(或将允许(使用转换构造函数进行转换。它甚至指的是[over.match.copy]

[过.配.复制]

。候选函数的选择如下:

  • T 的转换构造函数 ([class.conv.ctor]( 是候选函数。

第一个引号的问题延续:

。调用转换函数的结果...

没有明确说明不考虑转换构造函数,而是假设"转换函数"涵盖了此上下文中所有可能的用户定义转换。

因此,我怀疑这不是不考虑转换构造函数的意图,而是规则的措辞是一种疏忽。它可能源于这样一个事实,即转换构造函数也是执行转换的函数,因此术语"转换函数"描述了它们,即使这是其他类型的用户定义转换的确切名称。

如果我的怀疑是正确的,那么这条规则可能应该重新措辞。

最新更新