使用带有比较结构的lower_bound将对象插入矢量
Inserting objects into vector using lower_bound with compare struct
我有这个类:
class Mail {
public:
Mail(const string & msg) : msg(msg) {}
const string msg;
};
以及这个结构,它比较两个 Mail 对象:
struct Compare {
bool operator()(const Mail & mail, Mail const & mail2) const {
return mail.msg < mail2.msg;
}
};
我想有一个向量,其中包含按消息const string msg
排序的邮件对象。但是,当我尝试使用lower_bound
将新对象插入矢量时,我收到许多错误,包括:
将"const 字符串"作为"this"参数传递会丢弃限定符。
int main() {
vector <Mail> mails;
Mail mail2("1");
mails.push_back(mail2);
const string msg = "2";
Mail mail(msg);
auto low = lower_bound(mails.begin(), mails.end(), mail, Compare());
// mails.push_back(mail); // OK
mails.insert(low, mail); // passing ‘const string as ‘this’ argument discards qualifiers
return 0;
}
我还不太了解const
用法,也想不通,哪个const
错了。
很抱歉,如果已经问过这个问题,但我还没有找到这个问题的答案。
C++中的错误有时很难诊断。我的建议是始终从顶部开始,然后首先解决这个问题。在这种情况下,它们的列表很长,但它们实际上都是关于同一件事 - 无法生成Mail
赋值运算符。
这样想,编译器很有帮助,并试图生成(并在lower_bound()
内部使用)这个函数:
Mail& operator=( const& Mail mail )
{
msg = mail.msg;
return *this;
}
但不能,因为身体中的分配由于msg
const
而无效。您也不能自己编写它,因为您也无法分配给const
变量。
通常你不需要const
成员变量,因为如果类的实例本身const
,它们就会变得const
:
const auto mail1 = Mail{"1"};
auto mail2 = Mail{"2"};
mail1.msg = "3"; // FAIL! msg is const since mail1 is const
mail2.msg = "4"; // Ok! msg is not const
如果确实需要const
成员,则不能对类使用赋值运算符。 他们是休息时间。
删除该const
,一切正常:
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
class Mail {
public:
Mail(const string & msg) : msg(msg) {}
string msg; //////////////////////////////// Not const!
};
struct Compare {
bool operator()(const Mail & mail, Mail const & mail2) const {
return mail.msg < mail2.msg;
}
};
int main() {
vector <Mail> mails;
Mail mail2("1");
mails.push_back(mail2);
const string msg = "2";
Mail mail(msg);
auto low = lower_bound(mails.begin(), mails.end(), mail, Compare());
// mails.push_back(mail); // OK
mails.insert(low, mail); // OK!
return 0;
}
看到它在科利鲁上直播。
脚注:
- 你可以使用lambda作为比较器,以避免类
Compare
周围的一些样板
:
const auto low = lower_bound( begin(mails), end(mails), mail,
[]( const auto& mail1, const auto& mail2 )
{ return mail1.msg < mail2.msg; } );
- 您可以使用
vector::emplace_back()
就地构造项目,避免复制。以下块实际上执行相同的操作,但第二个块更有效:
const auto mail = Mail{"2"};
mails.push_back( mail2 ); // Copies
mails.emplace_back("2"); // Creates it right in the vector
- 如果您知道要在载体中放入多少项,请考虑使用
vector::reserve()
。
此处的问题与已删除的复制赋值运算符和已删除的移动赋值运算符有关,因为Mail
类中的const string msg;
成员:
删除了隐式声明的复制赋值运算符
如果满足以下任一条件,则类
T
的默认复制赋值运算符定义为已删除:
T
有一个非类类型(或其数组)的非静态数据成员,该成员const
;删除了隐式声明的移动赋值运算符
如果满足以下任一条件,则类
T
的隐式声明或默认移动赋值运算符定义为已删除:
- T 有一个非静态数据成员,该成员
const
;
相关文章:
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- CMake-按正确顺序将项目与C运行时对象文件链接
- 空基优化子对象的地址
- 将对象数组的引用传递给函数
- 你能重载对象变量名本身返回的内容吗
- C++使用整数的压缩数组初始化对象
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 将对象移动到std::shared_ptr
- 代理对象的常量正确性
- 提升 ASIO 无法识别计时器对象
- 将Ref对象作为类成员
- 将包含C样式数组的对象初始化为成员变量(C++)
- 如何返回一个类的两个对象相加的结果
- 使用std::函数映射对象方法
- 是否需要删除包含对象的"pair"?
- 如何在自删除后将对象设置为nullptr
- 迭代时从向量和内存中删除对象
- 构造对象的歧义
- 使用"std::unordereded_map"映射到"std::list"对象