使用 lower_bound 和比较结构将对象插入向量
Inserting objects into vector using lower_bound with compare struct
我有这个class:
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
将新对象插入到向量中时,出现许多错误,包括:
passing ‘const string as ‘this’ argument discards qualifiers.
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
是错误的。
很抱歉,如果有人问过这个问题,但我还没有找到这个问题的答案。
由于 Mail
class 中的 const string msg;
成员,此处的问题与删除的复制赋值运算符和删除的移动赋值运算符有关 class:
Deleted implicitly-declared copy assignment operator
A defaulted copy assignment operator for class T
is defined as deleted if any of the following is true:
T
has a non-static data member of non-class type (or array thereof) that is const
;
Deleted implicitly-declared move assignment operator
The implicitly-declared or defaulted move assignment operator for class T
is defined as deleted if any of the following is true:
- T has a non-static data member that is
const
;
C++ 中的错误有时很难诊断。我的建议是始终从头开始,首先解决那个问题。在这种情况下,有 a long list of them,但它们实际上都是关于同一件事的——无法生成 Mail
的赋值运算符。
这样想,编译器很有帮助,正在尝试生成(并在 lower_bound()
内部使用)这个函数:
Mail& operator=( const& Mail mail )
{
msg = mail.msg;
return *this;
}
但不能,因为正文中的赋值无效,因为 msg
为 const
。你也不能真正自己写,因为你也不能分配给 const
变量。
通常你不需要成员变量是const
,因为如果class的实例本身是const
:[=32=,它们就会变成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
成员,则不能对 class 使用赋值运算符。他们是休息时间。
删除 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.
上观看 运行
脚注:
- 您可以对比较器使用 lambda 以避免在 class
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()
。
我有这个class:
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
将新对象插入到向量中时,出现许多错误,包括:
passing ‘const string as ‘this’ argument discards qualifiers.
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
是错误的。
很抱歉,如果有人问过这个问题,但我还没有找到这个问题的答案。
由于 Mail
class 中的 const string msg;
成员,此处的问题与删除的复制赋值运算符和删除的移动赋值运算符有关 class:
Deleted implicitly-declared copy assignment operator
A defaulted copy assignment operator for class
T
is defined as deleted if any of the following is true:
T
has a non-static data member of non-class type (or array thereof) that isconst
;Deleted implicitly-declared move assignment operator
The implicitly-declared or defaulted move assignment operator for class
T
is defined as deleted if any of the following is true:
- T has a non-static data member that is
const
;
C++ 中的错误有时很难诊断。我的建议是始终从头开始,首先解决那个问题。在这种情况下,有 a long list of them,但它们实际上都是关于同一件事的——无法生成 Mail
的赋值运算符。
这样想,编译器很有帮助,正在尝试生成(并在 lower_bound()
内部使用)这个函数:
Mail& operator=( const& Mail mail )
{
msg = mail.msg;
return *this;
}
但不能,因为正文中的赋值无效,因为 msg
为 const
。你也不能真正自己写,因为你也不能分配给 const
变量。
通常你不需要成员变量是const
,因为如果class的实例本身是const
:[=32=,它们就会变成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
成员,则不能对 class 使用赋值运算符。他们是休息时间。
删除 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.
上观看 运行脚注:
- 您可以对比较器使用 lambda 以避免在 class
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()
。