首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在对文件系统路径的向量排序时,“取消引用过去的迭代器”。

在对文件系统路径的向量排序时,“取消引用过去的迭代器”。
EN

Stack Overflow用户
提问于 2019-08-03 13:19:18
回答 1查看 561关注 0票数 3

我正在使用std::文件系统编写一个简单的文件选择器。当前目录的条目存储在向量中。当我尝试用std::sort对向量排序时,程序崩溃了。

这发生在Ubuntu19.04上的g++-9上。该文件使用-D_GLIBCXX_DEBUG和-D_GLIBCXX_DEBUG_PEDANTIC调试标志进行编译。

相关代码如下:

代码语言:javascript
复制
#include <filesystem>
#include <vector>
#include <algorithm>

namespace fs = std::filesystem;

struct FileBrowser {
    std::vector<fs::path> files;

    FileBrowser() {
        UpdateFiles();
    }

    void UpdateFiles() {
        files.clear();
        for (const auto& entry : fs::directory_iterator(currentPath)) {
            files.push_back(entry.path());
        }


        std::sort(files.begin(), files.end(), [](const auto& lhs, const auto& rhs) {
            if (fs::is_directory(lhs) && !fs::is_directory(rhs)) {
                return 1;
            } else if (fs::is_directory(rhs) && !fs::is_directory(lhs)) {
                return 0;
            } else {
                return lhs.filename().string().compare(rhs.filename().string());
            }
        });
    }
};

错误消息如下所示:

代码语言:javascript
复制
/usr/include/c++/9/debug/safe_iterator.h:294:
In function:
    __gnu_debug::_Safe_iterator<_Iterator, _Sequence, _Category>::reference 
    __gnu_debug::_Safe_iterator<_Iterator, _Sequence, 
    _Category>::operator*() const [with _Iterator = 
    __gnu_cxx::__normal_iterator<std::filesystem::__cxx11::path*, 
    std::__cxx1998::vector<std::filesystem::__cxx11::path, 
    std::allocator<std::filesystem::__cxx11::path> > >; _Sequence = 
    std::__debug::vector<std::filesystem::__cxx11::path>; _Category = 
    std::forward_iterator_tag; __gnu_debug::_Safe_iterator<_Iterator, 
    _Sequence, _Category>::reference = std::filesystem::__cxx11::path&]

Error: attempt to dereference a past-the-end iterator.

Objects involved in the operation:
    iterator "this" @ 0x0x7fff6c67d9d0 {
      type = __gnu_cxx::__normal_iterator<std::filesystem::__cxx11::path*, std::__cxx1998::vector<std::filesystem::__cxx11::path, std::allocator<std::filesystem::__cxx11::path> > > (mutable iterator);
      state = past-the-end;
      references sequence with type 'std::__debug::vector<std::filesystem::__cxx11::path, std::allocator<std::filesystem::__cxx11::path> >' @ 0x0x55ca5b4536c0
    }

我在网上看到了很多用vector.end()调用std::sort的例子。我用files.end() - 1试了一下,并收到了同样的错误消息。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-08-03 13:57:35

std::sort需要严格的弱排序比较器,如[alg.sorting]/p3中所述

..。对于alg.binary.search中所描述的算法以外的算法,comp应该对这些值进行严格的弱排序。

严格的弱排序比较器只应在左手操作数先于右手操作数时返回true,而false则返回。

如果字符串在字典上小于参数表达式、等于或大于参数表达式,则std::basic_string::compare函数将其结果编码为<00>0。这允许在一次传递中确定其参数之间的相互关系。然而,正值和负值都隐式地可转换为true布尔值,因此任何标准库算法都会对结果进行错误解释,从而导致未定义的行为。为了避免这种情况,std::sort函数调用可以如下所示:

代码语言:javascript
复制
std::sort(files.begin(), files.end(), [](const auto& lhs, const auto& rhs) {
    if (fs::is_directory(lhs) && !fs::is_directory(rhs)) {
        return true;
    } else if (fs::is_directory(rhs) && !fs::is_directory(lhs)) {
        return false;
    } else {
        return lhs.filename().string() < rhs.filename().string();
        //                            ~^~
    }
});
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57338696

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档