调用类模板中隐式删除的复制构造函数
Call to implicitly deleted copy constructor in a class template
>我已经编写了一个类模板,只想有条件地使复制构造函数可用。为此,我想应用一些 SFINAE 技巧,并且需要使复制构造函数模板化。
像这样:
template <typename U = T, std::enable_if_t<std::is_same_v<U, T> && /* conditions on U */> * = nullptr>
Foo(const Foo<U> &);
但是,我遇到了问题,因为我定义了正常的移动构造函数,并且编译器抱怨由于我的用户定义的移动构造函数,它隐式删除了复制构造函数。它不想与我编写的模板化复制构造函数匹配。
我有以下示例代码重现我的问题:
template <typename T>
struct Foo final
{
Foo() = default;
template <typename U = T>
Foo(const Foo<U> &);
Foo(Foo<T> &&);
};
int main()
{
auto f1 = Foo<int>{};
auto f2 = Foo<int>{f1};
}
在 Godbolt 上使用 Clang 9.0.0 进行编译时,我收到以下错误:
<source>:15:15: error: call to implicitly-deleted copy constructor of 'Foo<int>'
auto f2 = Foo<int>{f1};
^ ~~~~
<source>:9:5: note: copy constructor is implicitly deleted because 'Foo<int>' has a user-declared move constructor
Foo(Foo<T> &&)
^
1 error generated.
Compiler returned: 1
编译错误仅描述症状,而不是我的实际错误。我通常可以推断出我做错了什么,但在这种情况下,因为在构造函数上使用 SFINAE 对我来说是很新的,所以我无法找出错误的根本原因。
任何人都可以帮我修复代码以实现我的目标吗?
编译器确实描述了你的实际错误:
<source>:9:5: note: copy constructor is implicitly deleted because 'Foo<int>' has a user-declared move constructor
Foo(Foo<T> &&)
解决方案:添加复制构造函数(签名:Foo(const Foo<T>&)
(或删除移动构造函数(即允许编译器生成复制构造函数(。
请注意,template <typename U = T> Foo(const Foo<U> &);
不是复制构造函数,因为它是模板化的。复制构造函数不得是模板化的。
相关文章:
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 为什么类中的ostringstream类型的成员会导致";调用隐含删除复制构造函数";错误
- std::ofstream 作为类成员删除复制构造函数?
- 删除复制构造函数的 Intel 13.1.2 中不良C++行为的解决方法
- c++17在编译时将带有已删除复制构造函数的类添加到std::vector
- 删除复制构造函数是否也会删除默认的复制/移动运算符?
- 用于删除复制/移动分配运算符的有效签名
- 为什么在具有引用字段的类中隐式删除复制运算符
- 为什么当类具有引用成员时C++编译器不删除复制构造函数
- 删除复制构造函数和运算符=类范围访问
- 是否可以使用 lambda 初始化变量(删除复制 ctor 时)
- 删除复制和复制转让 - 公共、私有还是受保护?
- 是否可以在基类中删除复制和移动构造函数/分配运算符
- 为什么具有已删除复制构造函数的结构不是 POD 类型
- 为什么删除复制构造函数会影响用户定义的默认构造函数?
- 带有向量的unique_ptr:错误:xxx的隐式删除复制构造函数
- 当提供用户定义的移动构造函数时,Visual Studio 2013不会删除复制构造函数
- 删除复制构造函数或复制赋值运算符算"user declared"吗?
- 为什么我们需要删除复制赋值运算符中的指针
- 卸载程序不会删除复制到VS2010安装程序项目中的系统文件夹。