为什么有一个复制构造函数导致此代码中断?

时间:2017-02-17 02:40:20

标签: c++ copy-constructor

所以我有这段代码:

template<class T>
struct IntegerType
{
    T value;

    //Next line causes errors
    //constexpr IntegerType(IntegerType& value) : value(value.value) { }
    constexpr IntegerType(T value) : value(value) { }
};
template<class int_t>
class FullMult{
    int_t value;
    int_t carry;
    public:

    constexpr FullMult() : value(0), carry(0) { }
    constexpr FullMult(const int_t& value, const int_t& carry) : value(value), carry(carry) { }

};

int main()
{
    FullMult<IntegerType<unsigned int> > thing 
        = FullMult<IntegerType<unsigned int> >(
            IntegerType<unsigned int>(12),IntegerType<unsigned int>(12));
}

但是当我尝试通过取消注释行IntegerType来向类型constexpr IntegerType(IntegerType& value) : value(value.value) { }添加复制构造函数时代码中断并告诉我我正在尝试使用{{1}的复制构造函数} type:

FullMult

这是给我错误的代码:

use of deleted function 'FullMult<IntegerType<unsigned int> >::FullMult(FullMult<IntegerType<unsigned int> >&&)'

这里发生了什么?

1 个答案:

答案 0 :(得分:4)

问题在于:

constexpr FullMult(const int_t& value, const int_t& carry) : value(value), carry(carry)

使用类型为int_t value;的参数初始化类成员const int_t。但是没有匹配的构造函数。 IntegerType拷贝构造函数接受非const引用,并且不能绑定到const int_t

但是,即使您单独修复此行,也会出现第二个问题,即错误消息中显示的问题。代码(为清晰起见缩写):

F thing = F(...bla...);

调用F的move-constructor。或者至少,即使操作被省略,它也会执行复制/移动可行性检查。但如错误消息所示,F(F&&)将被删除。这是因为默认定义是:

F(F&& other): value(std::move(other.value)), carry(std::move(other.carry)) {}

但是IntegerType没有匹配的构造函数 - 采用非const左值引用的复制构造函数不会绑定到xvalue std::move(other.value)

通过使IntegerType复制构造函数接受const引用,可以解决这两个问题。

或者,除了copy-constructor之外,还可以通过赋予IntegerType一个move-constructor来解决第二个问题。 (但第一个问题仍然存在)。