iostream GCC错误,转换为boost::filesystem::iostream for Windows

iostream GCC errors, converting to boost::filesystem::iostream for Windows

本文关键字:iostream filesystem for Windows boost GCC 错误 转换      更新时间:2023-10-16

我正在尝试将一个用C++14编写的应用程序转换为linux/MacOS。它使用boost::文件系统,但不用于某些iostream操作。例如:

boost::filesystem::path file = name;
std::ifstream fin(file.c_str());

此代码无法在Windows 10上使用带有GCC 6.3的MinGW进行编译,如下所示:

错误:没有用于调用的匹配函数'std::basic_ifstream::basic_ifstream(const value_type*)'std::ifstream-fin(file.c_str());

我想如果我能将std::ifstream转换为boost::filesystem::ifstream,我就能让它工作。。。所以我把代码改成了这个:

boost::filesystem::path file = name;
boost::filesystem::ifstream fin(file.c_str());
if (!fin)
{
file = pathToAppData / "files/expansion/assets/resources/basestation/config/mapFiles/racing" / name;
fin = boost::filesystem::ifstream(file.c_str());
if (!fin)
throw std::runtime_error(std::string("Cannot open Anki Overdrive map file ") + file.string() + ".");
}
fin >> (*this);

这导致了这个错误:

错误:'const-boost::filesystem::basic_ifstream&boost::filesystem::basic_ifstream::operator=(constboost::filesystem::basic_ifstream&)[其中charT=char;tracts=std::char_traits]'在此上下文中是私有的
fin=boost::filesystem::ifstream(file.c_str());

看起来我无法在创建后重新分配boost::filesystem::ifstream。。。我能够将该行更改为以下内容并进行编译,但我想知道这是否是正确的方法:

boost::filesystem::ifstream fin(file.c_str());

额外的问题:一旦我让它工作起来,这个代码应该在linux上也工作吗?

在Windows上,boost::filesystem::path::value_typewchar_t,因为Windows路径使用16位UTF-16字符的字符串。根据C++标准,std::ifstream类只有一个采用窄字符字符串的构造函数。Visual Studio标准库向ifstream添加了额外的构造函数,这些构造函数采用宽字符串,但MinGW使用的GCC标准库没有这些额外的构造函数。这意味着file.c_str()返回的const wchar_t*对于std::ifstream的构造函数参数是错误的类型。

您可以将path转换为窄字符串(通过调用file.string()),并将其传递给ifstream构造函数,尽管我不知道它是否能正常工作:

boost::filesystem::path file = name;
std::ifstream fin(file.string());

正如您所说,boost::filesystem::ifstream是不可分配的(在C++11流不可移动或分配之前,Boost.Filesystem流似乎还没有更新)。您可以简单地更改代码,使用相同的流对象重新打开一个新文件,而不是尝试重新分配给它:

fin.close();
fin.open(file);

(请注意,您不需要调用c_str(),因为boost::filesystem::ifstream构造函数无论如何都会获取path参数,而不是指向字符串的指针。通过调用c_str(),您只需将path转换为字符串,然后将其转换回另一个path,这会浪费时间和内存。)

额外的问题:一旦我让它工作起来,这个代码应该在linux上也工作吗?

是。在GNU/Linux上,filesystem::path::value_typechar,因此原始代码无论如何都可以正常工作。修改后的代码也将在GNU/Linux上运行。