Bra*_*rad 1 c++ boost iostream c++11
我正在尝试将用 C++14 编写的应用程序转换为 Linux/MacOS。它使用 boost::filesystem,但不适用于某些 iostream 操作。例如:
boost::filesystem::path file = name;
std::ifstream fin(file.c_str());
Run Code Online (Sandbox Code Playgroud)
此代码无法在 Windows 10 上使用 MinGW 和 GCC 6.3 进行编译,如下所示:
错误:没有匹配的函数可用于调用 '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);
Run Code Online (Sandbox Code Playgroud)
这导致了这个错误:
错误:'const boost::filesystem::basic_ifstream& boost::filesystem::basic_ifstream::operator=(const boost::filesystem::basic_ifstream&) [with charT = char; Traits = std::char_traits]' 在此上下文中是私有的
fin = boost::filesystem::ifstream(file.c_str());
看起来我一旦创建就无法重新分配 boost::filesystem::ifstream ...我能够将该行更改为以下内容并进行编译,但我想知道这是否是正确的方法:
boost::filesystem::ifstream fin(file.c_str());
Run Code Online (Sandbox Code Playgroud)
额外问题:一旦我让这段代码运行起来,它也应该在 Linux 上运行吗?
在 Windows 上boost::filesystem::path::value_type是wchar_t,因为 Windows 路径使用 16 位 UTF-16 字符的字符串。根据 C++ 标准,该类std::ifstream只有一个采用窄字符字符串的构造函数。Visual Studio 标准库添加了额外的构造函数来ifstream接受宽字符串,但 MinGW 使用的 GCC 标准库没有这些额外的构造函数。这意味着const wchar_t*by 返回的file.c_str()构造函数参数的类型是错误的std::ifstream。
您可以将 转换path为窄字符串(通过调用file.string())并将其传递给ifstream构造函数,尽管我不知道它是否能正常工作:
boost::filesystem::path file = name;
std::ifstream fin(file.string());
Run Code Online (Sandbox Code Playgroud)
正如您所说,boost::filesystem::ifstream是不可分配的(在 C++11 流之前不可移动或可分配,并且 Boost.Filesystem 流似乎尚未更新)。您可以简单地更改代码以使用相同的流对象重新打开新文件,而不是尝试重新分配给它:
fin.close();
fin.open(file);
Run Code Online (Sandbox Code Playgroud)
(请注意,您不需要调用c_str(),因为boost::filesystem::ifstream构造函数无论如何都采用path参数,而不是指向字符串的指针。通过调用,c_str()您只需将 转换path为字符串,然后将其转换回另一个path,这会浪费时间和内存。)
额外问题:一旦我让这段代码运行起来,它也应该在 Linux 上运行吗?
是的。在 GNU/Linux 上filesystem::path::value_type是char这样,所以原始代码无论如何都可以正常工作。修改后的代码也可以在 GNU/Linux 上运行。