C ++拷贝初始化+隐式构造函数call = fail

时间:2013-02-16 21:17:51

标签: c++ c++11 constructor implicit-conversion copy-initialization

此代码:

class foo
{
    int x;
public:
    foo(int x) : x(x) { }
    int get() const { return x; }
    //...
};

class bar
{
    int x;
public:
    bar(const foo& x) : x(x.get()) { }
    int get() const { return x; }
    bar& operator =(const foo& rhs) { x = rhs.get(); return *this; }
    //...
};

void func()
{
    foo f = 3;
    bar b = 3;
    b = 7;
    //...
}

bar b = 3行上的错误(g ++ 4.7.1 with -fstd=gnu++11):

error: conversion from 'int' to non-scalar type 'bar' requested

但是,我提供的bar构造函数采用foo,并且int可以隐式转换为foo,如前面的行所示。出了什么问题?

顺便说一句,由于多种原因,不希望使用foo强制转换为foo(3),因为这会使我的实际代码难以使用和阅读。

2 个答案:

答案 0 :(得分:5)

  

我提供了一个带有foo的bar构造函数,并且int可以隐式转换为foo,如前面的行所示。出了什么问题?

C ++中不允许链式转换,这意味着不会发生(链式)转换:

int -> foo -> bar  //not allowed (chained conversion)

即使给出以下内容:

int -> foo  //given
foo -> bar  //given

因此,如果您希望int -> bar正常工作,请添加另一个将int带到课程bar的构造函数。

答案 1 :(得分:0)

§13.3.3.1.2/ 1关于隐式用户定义的转换序列命令:

  

用户定义的转换序列包括初始标准转换序列,后跟用户定义的转换(12.3),然后是第二个标准转换序列。如果用户定义的转换由构造函数(12.3.1)指定,则初始标准转换序列将源类型转换为构造函数的参数所需的类型。如果转换函数(12.3.2)指定了用户定义的转换,则初始标准转换序列会将源类型转换为转换函数的隐式对象参数。

这意味着无法链接多个用户定义的转换。