繁体   English   中英

直接对象初始化与使用转换函数进行初始化

[英]Direct object initialization vs Initialization with convertion functions

以下程序打印42:

#include <iostream>

struct A
{
    operator int(){ return 42; }
};

struct B
{
    operator A(){ return A(); }
};

B b;
int a = A(b);    
int main(){ std::cout << a << std::endl; } //42

DEMO

但是,如果我们尝试定义cope / move或同时定义两个构造器,则将无法使用。

#include <iostream>

struct A
{
    A(A&&){ std::cout << "A(A&&)" << std::endl; }
    A(A&){ std::cout << "A(A&)" << std::endl; }
    operator int(){ return 42; }
};

struct B
{
    operator A(){ return A(); }
};

B b;
int a = A(b);

int main(){ std::cout << a << std::endl; } //Error

DEMO

我以为相关部分描述了行为是N4296::8.5/17.7 [dcl.init]

如果目标类型是(可能是cv限定的)类类型:

[...]

—否则,如果源类型是(可能是cv限定的)类类型,则考虑转换函数。 列举了适用的转换函数(13.3.1.5),并通过过载分辨率(13.3)选择了最佳转换函数。 如此选择的用户定义转换将被调用,以将初始化器表达式转换为正在初始化的对象。 如果转换无法完成或模棱两可,则初始化格式错误。

它不应该取决于构造函数的存在与否。 我们只需要具有适当的转换功能即可选择转换顺序。

您有效地删除了默认构造函数。 从标准(12.1 / 4,重点是我的):

对于A类默认构造函数X是类的构造函数X ,可以不带参数调用。 如果类X没有用户声明的构造函数,则将不带参数的构造函数隐式声明为默认值

如果没有用户声明的构造函数。 但是您声明了两个,因此没有隐式默认构造函数。 因此,这:

operator A(){ return A(); }
                  // ^^^

无法编译。 这就是为什么你得到的错误是

错误:没有匹配的函数可以调用A::A()

该代码尝试调用您的转换运算符-但该正文无效。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM