const std::filesystem::path reference constness 不被尊重,这是我做错了什么吗?

Const std::filesystem::path reference constness is not respected, is this something I did wrong?

我正在处理一个文件遍历项目,我想跟踪当前正在检查的项目,所以我有一个外部 filesystem::path CurrentItem 值,我会在每个 level/step 上更改它遍历以保持最新。

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

当遍历超出循环的入口深度时,当我用循环的 directory_entry 路径更新 CurrentItem 路径时,函数参数 path 也以某种方式设置.这让我感到莫名其妙,尤其是考虑到添加手表时它向我展示了即使底层 wstring 也被标记为 const,所以我不知所措。

最重要的是,我想知道我是否做错了足以破坏 const 的事情,或者它是否真的是一个我只需要解决的错误。我可以只创建一个辅助 path 并将输入值分配给它,并且它与 const 参数没有相同的问题,或者我可以将参数更改为普通的 const path,但这两种解决方案都重新引入了我想避免的额外不必要的副本。

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

我按原样复制了所有外部变量,减去 class 封装。我在 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& 将看到这些修改。