【问题标题】:iostream GCC errors, converting to boost::filesystem::iostream for Windowsiostream GCC 错误,转换为 boost::filesystem::iostream for Windows
【发布时间】:2017-05-21 18:58:41
【问题描述】:

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

boost::filesystem::path file = name;

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

此代码无法在 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);

这导致了这个错误:

错误:'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());

额外问题:一旦我让它工作,这段代码是否也能在 linux 上工作?

【问题讨论】:

  • 什么是name?你能把它传递给ifstream 构造函数吗?

标签: c++ c++11 boost iostream


【解决方案1】:

在 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 上运行。

【讨论】:

    猜你喜欢
    • 2017-07-02
    • 2016-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-16
    • 2010-09-20
    相关资源
    最近更新 更多