为什么拥有复制构造函数会导致此代码中断?
Why does having a copy constructor cause this code to break?
所以我有这个代码:
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));
}
但是当我尝试通过取消注释行 constexpr IntegerType(IntegerType& value) : value(value.value) { }
来向类型 IntegerType
添加复制构造函数时,代码中断并告诉我我正在尝试使用 FullMult
类型:
use of deleted function 'FullMult<IntegerType<unsigned int> >::FullMult(FullMult<IntegerType<unsigned int> >&&)'
这是给我错误的代码:
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));
}
这是怎么回事?
在线有一个问题:
constexpr FullMult(const int_t& value, const int_t& carry) : value(value), carry(carry)
您使用 const int_t
类型的参数初始化 class 成员 int_t value;
。但是没有匹配的构造函数。 IntegerType
copy-constructor 接受 non-const 引用并且不能绑定到 const int_t
.
但是,即使您独立修复此行,还有第二个问题,即出现在您的错误消息中的问题。代码(为清楚起见缩写):
F thing = F(...bla...);
调用 F
的 move-constructor。或者至少,它会执行 copy/move 可访问性检查,即使该操作被省略也是如此。但是如错误消息所示,F(F&&)
被删除了。这是因为默认定义为:
F(F&& other): value(std::move(other.value)), carry(std::move(other.carry)) {}
但是 IntegerType
没有匹配的构造函数——采用 non-const 左值引用的 copy-constructor 没有绑定到 xvalue std::move(other.value)
.
这两个问题都可以通过使 IntegerType
复制构造函数接受 const 引用来解决。
或者,除了 copy-constructor 之外,还可以通过给 IntegerType
一个 move-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));
}
但是当我尝试通过取消注释行 constexpr IntegerType(IntegerType& value) : value(value.value) { }
来向类型 IntegerType
添加复制构造函数时,代码中断并告诉我我正在尝试使用 FullMult
类型:
use of deleted function 'FullMult<IntegerType<unsigned int> >::FullMult(FullMult<IntegerType<unsigned int> >&&)'
这是给我错误的代码:
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));
}
这是怎么回事?
在线有一个问题:
constexpr FullMult(const int_t& value, const int_t& carry) : value(value), carry(carry)
您使用 const int_t
类型的参数初始化 class 成员 int_t value;
。但是没有匹配的构造函数。 IntegerType
copy-constructor 接受 non-const 引用并且不能绑定到 const int_t
.
但是,即使您独立修复此行,还有第二个问题,即出现在您的错误消息中的问题。代码(为清楚起见缩写):
F thing = F(...bla...);
调用 F
的 move-constructor。或者至少,它会执行 copy/move 可访问性检查,即使该操作被省略也是如此。但是如错误消息所示,F(F&&)
被删除了。这是因为默认定义为:
F(F&& other): value(std::move(other.value)), carry(std::move(other.carry)) {}
但是 IntegerType
没有匹配的构造函数——采用 non-const 左值引用的 copy-constructor 没有绑定到 xvalue std::move(other.value)
.
这两个问题都可以通过使 IntegerType
复制构造函数接受 const 引用来解决。
或者,除了 copy-constructor 之外,还可以通过给 IntegerType
一个 move-constructor 来解决第二个问题。 (但第一个问题仍然存在)。