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

时间:2015-01-25 05:42:14

标签: c++ class c++11

以下程序打印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)。用户定义的转换就是这样   调用selected来将初始化表达式转换为   对象被初始化。如果转换无法完成或是   暧昧,初始化是不正确的。

它不应该取决于构造函数的缺失/存在。我们只需要有适当的转换函数,以便选择转换序列。

1 个答案:

答案 0 :(得分:1)

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

  

X默认构造函数是类X的构造函数,可以在不带参数的情况下调用。 如果   对于类X 没有用户声明的构造函数,隐式声明没有参数的构造函数   默认

IF 没有用户声明的构造函数。但是你声明了两个,所以没有隐式的默认构造函数。因此,这个:

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

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

的原因
  

错误:没有匹配函数来调用A::A()

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