c++ - Const std::filesystem::path 引用常量不受尊重,这是我做错的吗?

标签 c++ windows c++17 boost-filesystem

我正在开发一个文件遍历项目,并且我想跟踪正在检查的当前项目,因此我有一个外部 filesystem::path CurrentItem 值,我在每个项目上更改该值遍历的级别/步骤以保持最新。

我正在使用递归函数,该函数采用 const filesystem::path& 来遍历文件,const path 引用而不是 path 本身,这样我就可以避免字符串复制开销。我知道从规模上看,这可能不是这个程序中最繁重的操作,但这是我选择做的。

当遍历超出循环的条目深度时,当我使用循环的 directory_entry 路径更新 CurrentItem 路径时,函数参数 path 也以某种方式被设置。这让我感到困惑,尤其是考虑到添加一个 watch 后,它向我显示,即使是底层的 wstring 也被标记为 const,所以我不知所措。

底线,我想知道我是否做了一些足以破坏 const 的错误,或者这实际上是一个我只需要解决的错误。我可以创建一个辅助 path,将输入值分配给它,并且不会出现与 const 参数相同的问题,或者我可以将参数更改为一个普通的 const 路径,但这两种解决方案都重新引入了我想避免的额外不必要的拷贝。

我在一个完全干净的环境中将代码从我的项目中分离出来,并且它表现出完全相同的行为。

我按原样重现了所有外部变量,减去类封装。我在 Windows 10 上的 VS19 中运行,在 32 位和 64 位上进行了测试,并且发生了同样的情况。这是:

#include <iostream>
#include <filesystem>

using namespace std::filesystem;

std::error_code ec;

path StartDirectory = L"D:/Camera Import/Animals/RAW";
path CurrentItem;
bool Recursive = true;
bool DoFiles = false;
bool DoFolders = true;

void HandleFilesInDirectory(const path& thisPath);

int main()
{
    std::cout << "Hello World!\n";

    StartDirectory.make_preferred();
    CurrentItem = StartDirectory;

    if (is_directory(StartDirectory, ec))
    {
        HandleFilesInDirectory(StartDirectory);
    }

}

void HandleFilesInDirectory(const path& thisPath)
{
    for (const directory_entry& entry : directory_iterator(thisPath))
    {
        auto type = entry.status().type();

        // This assignment operation causes the const path& thisPath to be reassigned somehow,
        // despite it being const and also being unrelated to the items in the assignment
        CurrentItem = entry.path();

        if (entry.is_directory(ec))
        {
            if (Recursive)
            {
                HandleFilesInDirectory(CurrentItem);
            }

            if (DoFolders)
            {
                // Do project-specific operations
            }
        }
        else if (DoFiles && entry.is_regular_file(ec))
        {
            // Do project-specific operations
        }
    }

    CurrentItem = thisPath;

    if (!thisPath.compare(StartDirectory))
    {
        // Do project-specific operations
    }
}

最佳答案

这就是当您使用可修改的全局变量时会发生的情况。

thisPath 引用的对象不能由 thisPath 变量修改,但如果有其他方法访问该对象,则它可以采用不同的值。例如,如果是对全局变量的引用,如果修改了该全局变量,那么引用的对象就被改变了。

当然,您的 HandleFilesInDirectory 函数会使用 CurrentItem 调用自身。这意味着对此函数的递归调用将获得对可修改全局变量的引用。然后您可以在函数中修改全局变量。

const& 只是通过该变量进行修改的保护措施。如果该对象可以通过其他方式修改,const& 将看到这些修改。

关于c++ - Const std::filesystem::path 引用常量不受尊重,这是我做错的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68910141/

相关文章:

C++ STL : list with Pointers - Iterator cannot access?

c++ - CMake 与 Visual Studio

C++整行在不应该的时候被着色

php - Uncaught Error : Call to undefined function pg_connect() using XAMPP on Windows

C++17:泛型(基于多重继承?)检查参数包中的模板

c++ - 在 C++ 中将 char 数组读取为 float 组,而无需使用 memcpy 复制它

c# - Emgu Opencv C# ConvertTo 不同的结果

c++ - 如何在 C++ 中将 ASCII 字符串转换为 UTF8 字符串?

c++ - 在Visual Studio Code中,为什么它会在类之外自动创建 “main::main and main::~main”?

c++ - 将包含重音字符的 UTF-8 字符串转换为 UTF-16