为什么 std::sort 抱怨已删除的复制者?

2024-04-19

假设我们有一个简单的类,其中包含std::string:

class StringWrapper {
public:
    const std::string s;

    StringWrapper(const std::string s)
        : s(s) {}

    // We want this to be moveable but not copyable
    ~StringWrapper() = default;
    StringWrapper(const StringWrapper&) = delete;
    StringWrapper& operator=(const StringWrapper&) = delete;
    StringWrapper(StringWrapper&&) noexcept = default;
    StringWrapper& operator=(StringWrapper&&) = default;
};

在这里,我们试图使类可移动,但不可复制。我明白,一个const成员变量通常会阻止生成默认的移动向量,但在这里我们尝试显式生成它 - 这至少可以编译。

现在我们尝试排序std::vector<StringWrapper>(比较函数在这里并不重要):

std::vector<StringWrapper> strings;
std::sort(strings.begin(), strings.end(), [](auto const& a, auto const& b) { return true; });

这无法编译,但错误非常神秘:

1>...\include\algorithm(7419,25): error C2280: 'StringWrapper &StringWrapper::operator =(const StringWrapper &)': attempting to reference a deleted function
1>...src\example.cpp(476): message : see declaration of 'StringWrapper::operator ='
1>...src\example.cpp(476,24): message : 'StringWrapper &StringWrapper::operator =(const StringWrapper &)': function was explicitly deleted
1>...\include\algorithm(7541): message : see reference to function template instantiation '_BidIt std::_Insertion_sort_unchecked<_RanIt,_Pr>(const _BidIt,const _BidIt,_Pr)' being compiled
1>        with
1>        [
1>            _BidIt=StringWrapper *,
1>            _RanIt=StringWrapper *,
1>            _Pr=myFunc::<lambda_8668e50965d967f7b587b72f59fcb0cf>
1>        ]
1>...\include\algorithm(7571): message : see reference to function template instantiation 'void std::_Sort_unchecked<StringWrapper*,_Fn>(_RanIt,_RanIt,int,_Pr)' being compiled
1>        with
1>        [
1>            _Fn=myFunc::<lambda_8668e50965d967f7b587b72f59fcb0cf>,
1>            _RanIt=StringWrapper *,
1>            _Pr=myFunc::<lambda_8668e50965d967f7b587b72f59fcb0cf>
1>        ]
1>...src\example.cpp(488): message : see reference to function template instantiation 'void std::sort<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<_Ty>>>,myFunc::<lambda_8668e50965d967f7b587b72f59fcb0cf>>(const _RanIt,const _RanIt,_Pr)' being compiled
1>        with
1>        [
1>            _Ty=StringWrapper,
1>            _RanIt=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<StringWrapper>>>,
1>            _Pr=myFunc::<lambda_8668e50965d967f7b587b72f59fcb0cf>
1>        ]
1>...\include\algorithm(7422,28): error C2280: 'StringWrapper &StringWrapper::operator =(const StringWrapper &)': attempting to reference a deleted function
1>...src\example.cpp(476): message : see declaration of 'StringWrapper::operator ='
1>...src\example.cpp(476,24): message : 'StringWrapper &StringWrapper::operator =(const StringWrapper &)': function was explicitly deleted
1>...\include\algorithm(7425,24): error C2280: 'StringWrapper &StringWrapper::operator =(const StringWrapper &)': attempting to reference a deleted function
1>...src\example.cpp(476): message : see declaration of 'StringWrapper::operator ='
1>...src\example.cpp(476,24): message : 'StringWrapper &StringWrapper::operator =(const StringWrapper &)': function was explicitly deleted

具体来说,它建议std::sort正在尝试引用已删除的复制者,但我不知道为什么会出现这种情况;我希望std::sort仅使用移动操作。

谁能向我解释一下这是怎么回事?


这已经在评论中涵盖了,但对于后代来说值得注意的是,使用default关键字不保证编译器始终会尝试创建特殊成员的默认实现。这(像往常一样)在关于移动赋值运算符的部分中得到了很好的解释参考参数 https://en.cppreference.com/w/cpp/language/move_assignment#Deleted_implicitly-declared_move_assignment_operator.

如果满足以下任一条件,则类 T 的隐式声明或默认移动赋值运算符被定义为已删除:

  • T 有一个非静态数据成员,即const.

编译器也会像这里一样抱怨这种情况。例如铿锵:

warning: explicitly defaulted move assignment operator is implicitly deleted [-Wdefaulted-function-deleted]
    StringWrapper& operator=(StringWrapper&&) = default;
                   ^
note: move assignment operator of 'StringWrapper' is implicitly deleted because field 's' has no move assignment operator
    const std::string s;

请注意,这是警告而不是错误,这就是您最终遇到这种情况的原因。一般来说,最好不要假设default关键字允许您绕过语言限制。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 std::sort 抱怨已删除的复制者? 的相关文章

  • 为什么使用abs()或fabs()而不是条件否定?

    在 C C 中 为什么要使用abs or fabs 不使用以下代码即可查找变量的绝对值 int absoluteValue value lt 0 value value 这与较低级别的指令较少有关吗 您提出的 有条件的abs 并不等于std
  • 检测到 NuGet 包的版本冲突

    我正在开发 ASP Net core 2 1 Web 应用程序项目 我的解决方案中有 1 个项目和 3 个其他库 它是高级架构 数据访问层 DAL 业务层 BL 公共层 CL 所以我需要添加引用来连接一些库和项目 我已经添加了CL参考我的项
  • Tensorflow 中的自定义资源

    由于某些原因 我需要为 Tensorflow 实现自定义资源 我试图从查找表实现中获得灵感 如果我理解得好的话 我需要实现3个TF操作 创建我的资源 资源的初始化 例如 在查找表的情况下填充哈希表 执行查找 查找 查询步骤 为了促进实施 我
  • C++ 中的软(不是:弱)引用 - 这可能吗?有实施吗?

    在 C 中我正在使用boost shared ptr and boost weak ptr自动删除不再需要的对象 我知道这些与引用计数一起工作 在 Java 中 内存由垃圾收集器管理 它将内置对象引用视为strong WeakReferen
  • Blazor 与 Razor

    随着 Blazor 的发明 我想知道这两种语言之间是否存在显着的效率 无论是在代码创建方面还是在代码的实际编译 执行方面 https github com SteveSanderson Blazor https github com Ste
  • 使用实体框架从集合中删除项目

    我正在使用DDD 我有一个 Product 类 它是一个聚合根 public class Product IAggregateRoot public virtual ICollection
  • 获取从属性构造函数内部应用到哪个属性的成员?

    我有一个自定义属性 在自定义属性的构造函数内 我想将属性的属性值设置为属性所应用到的属性的类型 是否有某种方式可以访问该属性所应用到的成员从我的属性类内部 可以从 NET 4 5 using CallerMemberName Somethi
  • 转到 C# WPF 中的第一页

    我正在 WPF 中使用导航服务 为了导航到页面 我使用 this NavigationService Navigate new MyPage 为了返回我使用 this NavigationService GoBack 但是如何在不使用的情况
  • 是否有与 C++11 emplace/emplace_back 函数类似的 C# 函数?

    从 C 11 开始 可以写类似的东西 include
  • Xamarin Android:获取内存中的所有进程

    有没有办法读取所有进程 而不仅仅是正在运行的进程 如果我对 Android 的理解正确的话 一次只有一个进程在运行 其他所有进程都被冻结 后台进程被忽略 您可以使用以下代码片段获取当前正在运行的所有 Android 应用程序进程 Activ
  • 单元测试失败,异常代码为 c0000005

    我正在尝试使用本机单元测试项目在 Visual Studios 2012 中创建单元测试 这是我的测试 TEST METHOD CalculationsRoundTests int result Calculations Round 1 0
  • 为什么 FTPWebRequest 或 WebRequest 通常不接受 /../ 路径?

    我正在尝试从 ftp Web 服务器自动执行一些上传 下载任务 当我通过客户端甚至通过 Firefox 连接到服务器时 为了访问我的目录 我必须指定如下路径 ftp ftpserver com AB00000 incoming files
  • 事件日志写入错误

    很简单 我想向事件日志写入一些内容 protected override void OnStop TODO Add code here to perform any tear down necessary to stop your serv
  • 组合框项目为空但数据源已满

    将列表绑定到组合框后 其 dataSource Count 为 5 但组合框项目计数为 0 怎么会这样 我习惯了 Web 编程 而且这是在 Windows 窗体中进行的 所以不行combo DataBind 方法存在 这里的问题是 我试图以
  • C# using 语句、SQL 和 SqlConnection

    使用 using 语句 C SQL 可以吗 private static void CreateCommand string queryString string connectionString using SqlConnection c
  • Qt - 设置不可编辑的QComboBox的显示文本

    我想将 QComboBox 的文本设置为某些自定义文本 不在 QComboBox 的列表中 而不将此文本添加为 QComboBox 的项目 此行为可以在可编辑的 QComboBox 上实现QComboBox setEditText cons
  • 通过等待任务或访问其 Exception 属性都没有观察到任务的异常

    这些是我的任务 我应该如何修改它们以防止出现此错误 我检查了其他类似的线程 但我正在使用等待并继续 那么这个错误是怎么发生的呢 通过等待任务或访问其 Exception 属性都没有观察到任务的异常 结果 未观察到的异常被终结器线程重新抛出
  • 32位PPC rlwinm指令

    我在理解上有点困难rlwinmPPC 汇编指令 旋转左字立即然后与掩码 我正在尝试反转函数的这一部分 rlwinm r3 r3 0 28 28 我已经知道什么了r3 is r3在本例中是一个 4 字节整数 但我不确定这条指令到底是什么rlw
  • 是否有一个 C++ 库可以从 PDF 文件中提取文本,例如 PDFBox for Java? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 去年 我使用 PDFBox 在 Java 中创建了一个应用程序来获取某些 PDF 文件中的原始文本 现在
  • 我应该在应用程序退出之前运行 Dispose 吗?

    我应该在应用程序退出之前运行 Dispose 吗 例如 我创建了许多对象 其中一些对象具有事件订阅 var myObject new MyClass myObject OnEvent OnEventHandle 例如 在我的工作中 我应该使

随机推荐