我上了这个课:
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;
}
};
我想要一个包含Mail对象的向量,这些对象按其消息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
是错误的。
很抱歉,如果已经问过这个问题,但是我还没有找到解决这个问题的答案。
答案 0 :(得分:0)
由于const string msg;
类中的Mail
成员,这里的问题与删除的副本分配运算符和删除的移动分配运算符有关:
Deleted implicitly-declared copy assignment operator
如果满足以下任一条件,则将类别
T
的默认副本分配运算符定义为已删除:
T
具有一个非类类型(或其数组)的非静态数据成员,即const
;Deleted implicitly-declared move assignment operator
对于类
T
的隐式声明或默认的移动分配运算符,如果满足以下任一条件,则定义为已删除:
- T具有一个非静态数据成员
const
;
答案 1 :(得分:0)
C ++中的错误有时很难诊断。我的提示是始终从顶部开始并首先解决该问题。在这种情况下,有a long list of them,但它们实际上是同一回事–无法生成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;
}
看到它在 Coliru 上实时运行。
脚注:
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()
。