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

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

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

boost::filesystem::path file = name;

std::ifstream fin(file.c_str());

此代码无法在 Windows 10 上使用 MinGW 和 GCC 6.3 进行编译,并具有以下内容:

error: no matching function for call to '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);

导致此错误:

error: 'const boost::filesystem::basic_ifstream& boost::filesystem::basic_ifstream::operator=(const boost::filesystem::basic_ifstream&) [with charT = char; traits = std::char_traits]' is private within this context
fin = boost::filesystem::ifstream(file.c_str());

看起来我无法重新分配 boost::filesystem::ifstream 一旦创建...我能够将该行更改为以下内容并编译,但我想知道它是否是正确的做法:

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

额外问题:此代码是否也适用于 linux?

在 Windows boost::filesystem::path::value_type 上是 wchar_t,因为 Windows 路径使用 16 位 UTF-16 字符的字符串。根据 C++ 标准,std::ifstream class 只有一个采用窄字符字符串的构造函数。 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,这会浪费时间和内存。)

Bonus question: Should this code work on linux as well once I get it working?

是的。在 GNU/Linux filesystem::path::value_type 上是 char,所以原始代码无论如何都可以正常工作。修改后的代码也适用于 GNU/Linux。