CPP:使用已删除功能

Posted

技术标签:

【中文标题】CPP:使用已删除功能【英文标题】:CPP: Use of deleted function 【发布时间】:2021-03-23 13:04:13 【问题描述】:

我正在尝试使用 c++ 中的 lambda 函数对包含自定义 struct 条目的向量进行排序。但是我收到以下错误消息提示

错误:使用已删除的函数‘dummy_struct& dummy_struct::operator=(const dummy_struct&)

代码如下所示:

#include <regex>

struct dummy_struct

    dummy_struct(std::string name, int64_t value_a) :
        name(name),
        value_a(value_a)
    
    
    const std::string name;
    const int64_t value_a;
    
    int ExtractNumberFromName(std::regex key)
    
        int retval;
        std::cmatch match;
        std::regex_search(this->name.c_str(),match,key);
        retval=std::stoi(match[0],nullptr);
        return retval;
    
    
;


void SortByCustomKey(const std::vector<dummy_struct> collection, std::regex key)


    auto compare = [key](dummy_struct a, dummy_struct b)
    
        return a.ExtractNumberFromName(key) > b.ExtractNumberFromName(key)
    ;
    
    std::sort(std::begin(collection),std::end(collection),compare);



int main()


    std::vector<dummy_struct> test;
    
    test.push_back(dummy_struct("Entry[1]",1));
    test.push_back(dummy_struct("Entry[2]",2));
    test.push_back(dummy_struct("Entry[3]",3));
    
    SortByCustomKey(test,std::regex("[0-9]+"));


我在这里错过了什么?

【问题讨论】:

你所有的字段都是const 那么分配怎么能做呢?一个const 字段足以防止编译器生成赋值运算符的默认实现。 您应该通过引用传递重要的参数,目前您的排序适用于 test 向量的副本。 @MarekR 我使用了const 表示法,因为这些字段一旦初始化就不应更改。这是否意味着通过调用 sort 我正在由于值被更改而产生问题? 见doc of std::sort:The type of dereferenced RandomIt must meet the requirements of MoveAssignable and MoveConstructible. @Broxigar 正确。 const 成员变量很痛苦 :-) 只需将它们设为 private 并且不要更改它们 - 除非正在完成复制或移动分配。 【参考方案1】:

std::sort 通过就地交换元素来对向量进行排序。

这要求您的类实现copy assignment operator(或移动赋值),由于类中的const 字段,编译器不会为您生成该类。对于您的示例,唯一的解决方案似乎是从字段中删除 const 限定符。如果您不想修改它们,只需将它们设为private 并且不要提供(公共)设置器。 如果它们绝对必须留在那里,而您只想按排序顺序获取值,则可以使用不同的结构或将指针存储在向量中。

另一种解决方案是为您的类编写一个自定义的swap 实现,该实现将const_cast 去掉字段的限定符以用于赋值,尽管这通常是一种不好的代码味道。

【讨论】:

以上是关于CPP:使用已删除功能的主要内容,如果未能解决你的问题,请参考以下文章

c_cpp 从已排序的链接列表中删除重复项

[cpp] 使用 shared_ptr的自定义删除函数模拟 go 语言的 defer 功能

c_cpp 从已排序的链表中删除重复值节点 - Hackerrank

c_cpp 给定一个已排序的链表,删除所有重复项,使每个元素只出现一次。

c_cpp 给定已排序的链接列表,删除所有具有重复数字的节点,只留下原始列表中的不同数字。

非法使用已删除功能