请注意,这里的问题已经解决了,它与插入无关,而是一个未初始化的结构成员变量!希望这个问题及其答案可以帮助其他菜鸟避免这样的错误。
我想将文件名的 std::vector 插入到 std::set 中,该 std::set 具有用于按日期而不是按字母顺序排序文件的客户排序器结构。
使用默认的字母顺序,我可以使用以下方法简单地将 vector 插入我的集合中:
std::set<std::string> mySet;
std::vector<std::string> myVector;
myVector.push_back("Banana.txt");
myVector.push_back("Apple.txt");
myVector.push_back("Cat.txt");
mySet.insert(myVector.begin(), myVector.end());
这将完全符合我的期望:一组按字母顺序排列的 std::文件名。
现在,如果我有一个按日期而不是文件名排序的自定义排序器,如下所示:
struct DateOrderSorter
{
bool operator()(const std::string& file1, const std::string& file2)
{
struct stat buf_stat1;
struct stat buf_stat2;
std::string fullpath1 = path + file1;
std::string fullpath2 = path + file2;
stat(&fullpath1[0], &buf_stat1);
stat(&fullpath2[0], &buf_stat2);
return buf_stat1.st_ctime < buf_stat2.st_ctime;
}
std::string path;
};
然后我将我的集合声明为:
std::set<std::string, DateOrderSorter>
然后声明一个 DateOrderSorter 的实例:
DateOrderSorter dateOrderSorter;
dateOrderSorter.path = "C:/random_path_that_has_been_verified_to_work"
当我做同样的插入时:
mySet.insert(myVector.begin(), myVector.end());
它只返回按日期排序的第一个和最后一个文件。所以只有 myVector.begin() 和 myVector.end()。
- 首先,为什么会出现这种行为?
- 我该怎么做才能通过我的客户分类器将 vector 插入到我的集合中。
我试过了
std::vector<std::string>::iterator vector_it = myVector.begin();
std::vector<std::string>::iterator vector_end = myVector.end();
for (; vector_it!= vector_end; ++vector_it) {
mySet.insert(*vector_it);
}
但这并没有完全复制 vector ,而且顺序很奇怪。它没有遵循姓名或日期顺序..
最佳答案
path
比较函数的成员默认初始化为“”,因此 stat
错误(错误未被注意到,因为代码中未检查返回值),以及 buf_stat1.st_ctime < buf_stat2.st_ctime
正在比较未初始化的内存。
这意味着比较函数可以为 a < b
返回 true和 a > b
: 这违反了 strict weak ordering 的规则,因此您会观察到这种奇怪的行为。
要解决此问题,您可以制作 path
静态成员,并验证 stat
不会出错,像这样:
struct DateOrderSorter
{
bool operator()(const std::string& file1, const std::string& file2)
{
struct stat buf_stat1;
struct stat buf_stat2;
std::string fullpath1 = path + file1;
std::string fullpath2 = path + file2;
int r = stat(&fullpath1[0], &buf_stat1);
assert(r==0);
r = stat(&fullpath2[0], &buf_stat2);
assert(r==0);
return buf_stat1.st_ctime < buf_stat2.st_ctime;
}
static std::string path;
};
然后像这样初始化它:
DateOrderSorter::path = "...";
关于c++ - 如何将 std::vector 插入具有自定义排序功能的 std::set,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51172214/