如何使用模板复制和移动构造函数和赋值运算符?
How to utilize template copy&move constructor and assignment operator?
请考虑以下C++代码,我尝试避免非模板复制和移动构造函数和赋值运算符的首选项失败:
template<typename T> class A {
public:
A() { /* implementation here */ }
// Remove from the overloads the default copy&move constructors and assignment operators
A(const A&) = delete;
A& operator=(const A&) = delete;
A(A&&) = delete;
A& operator=(A&&) = delete;
// I want these to be used e.g. by std::vector
template<typename U> A(const A<U>& fellow) { /* implementation here */ }
template<typename U> A& operator=(const A<U>& fellow) { /* implementation here */ }
template<typename U> A(A<U>&& fellow) { /* implementation here */ }
template<typename U> A& operator=(A<U>&& fellow) { /* implementation here */ }
};
但是,我收到以下错误
尝试引用已删除的函数
当尝试将A
项推送到向量或简单地复制构造时,例如:
A<int> a1{};
A<int> a2(a1);
UPDATE1:我需要模板复制和移动构造函数和赋值运算符,因为模板参数实际上只是控制一些缓存,因此A<T1>
可以安全地分配给A<T2>
。
您可以通过声明带有替代签名的已删除复制构造函数/赋值运算符来使编译器满意,这不会导致选择此重载,但会阻止编译器生成构造函数/赋值运算符:
template<typename T> class A
{ public:
A() { /* implementation here */ }
// Remove from the implicit declaration of the default copy&move constructors and assignment operators
A(A volatile const &) = delete;
A & operator =(A volatile const &) = delete;
// I want these to be used e.g. by std::vector
template<typename U> A(A<U> const & fellow) { /* implementation here */ }
template<typename U> A & operator =(A<U> const & fellow) { /* implementation here */ return *this;}
template<typename U> A(A<U> && fellow) { /* implementation here */ }
template<typename U> A & operator =(A<U> && fellow) { /* implementation here */ return *this; }
};
int main()
{
A<int> a1{};
A<int> a2{a1};
return 0;
}
在线编译器
15.8.1 复制/移动构造函数 [class.copy.ctor]
1.class X
的非模板构造函数是复制构造函数,如果它的第一个参数是类型X&
、const X&
、volatile X&
或const volatile X&
,并且没有其他参数,或者所有其他参数都有默认参数
复制
构造函数的最小示例,该构造函数使用第二个未使用(和默认)参数将执行委托给模板构造函数
#include <iostream>
template <typename T>
struct A
{
A()
{ }
A (A const & a0) : A{a0, 0}
{ }
template<typename U>
A (A<U> const &, int = 0)
{ std::cout << "template constructor" << std::endl; }
};
int main()
{
A<int> a0;
A<int> a1{a0};
}
--编辑--
OP问
operator=
呢?尝试添加虚拟参数会导致编译器错误binary 'operator =' has too many parameters and 'operator =' cannot have default parameters
对于operator=()
,我建议将两个运算符"委托"(在这种情况下不是委托构造函数的意思)两个运算符都使用普通方法;模板方法。
作为
template <typename U>
A & assign (A<U> const &)
{ /* do assignment */ return *this; }
A & operator= (A const & a0)
{ return assign(a0); }
template <typename U>
A & operator= (A<U> const & a0)
{ return assign(a0); }
也许assign()
方法可以是一个private
的方法。
或者更好,正如 Jarod42 所建议的那样(谢谢),直接从非模板运算符调用模板运算符
template <typename U>
A & operator= (A<U> const & a0)
{ /* do assignment */ return *this; }
A & operator= (A const & a0)
{ return operator=<T>(a0); }
相关文章:
- 为什么不调用移动构造函数?(默认情况下只有构造器,没有别的)
- std::vector::p ush_back() 不会在 MSVC 上编译具有已删除移动构造函数的对象
- 仅包含可移动 std::map 的类的移动构造函数不起作用
- 为什么调用复制构造函数而不是移动构造函数?
- 基类中的默认析构函数禁用子类中的移动构造函数(如果有成员)
- 从具有按值捕获的 lambda 移动构造 std::函数时,移动构造函数调用两次
- 移动构造函数和右值引用
- 为什么 std::memmove 中联合的默认非平凡移动构造函数C++?
- 具有专用化的模板类中的可靠条件复制和移动构造函数
- C++:为什么不调用移动构造函数?
- 移动构造函数永远不会被调用
- C++:关于使用 Stroustrup 示例移动构造函数/赋值的问题
- 运算符+ 的规范实现涉及额外的移动构造函数
- C ++为什么在移动构造函数中需要移动/前进
- 为什么在删除"移动构造函数"时使用"复制构造函数"?
- 为什么这里不调用移动构造函数?
- 隐式移动构造函数
- 如何为具有私有成员的派生类实现移动构造函数
- 为什么不调用移动构造函数
- 是否可以避免在以下代码中复制/移动构造函数的需要?