【问题标题】:Strange error: cannot convert from 'int' to 'ios_base::openmode'奇怪的错误:无法从“int”转换为“ios_base::openmode”
【发布时间】:2023-06-27 17:55:01
【问题描述】:

我正在使用 g++ 编译一些代码。我写了以下sn-p:

bool WriteAccess = true;
string Name = "my_file.txt";
ofstream File;
ios_base::open_mode Mode = std::ios_base::in | std::ios_base::binary;
if(WriteAccess)
  Mode |= std::ios_base::out | std::ios_base::trunc;
File.open(Name.data(), Mode);

我收到这些错误...知道为什么吗?

错误 1:从“int”到“std::_Ios_Openmode”的无效转换
错误 2:初始化 'std::basic_filebuf<_chart _traits>* std::basic_filebuf<_chart _traits>::open(const char*, std::_Ios_Openmode) 的参数 2 [with _CharT = char, _Traits = std: :char_traits]'

据我在 Google 搜索中得知,g++ 实际上在这里打破了 C++ 标准。我觉得这很令人惊讶,因为它们通常非常严格地符合标准。是这样吗?还是我做错了什么。

我的标准参考:http://www.cplusplus.com/reference/iostream/ofstream/open/

【问题讨论】:

  • 除了更正类型名称外,还应使用Name.c_str() 而不是Name.data(),因为std::string::data() 不返回以null 结尾的字符数组。

标签: c++ standards-compliance ofstream


【解决方案1】:

openmode 是正确的类型,而不是 open_mode。

【讨论】:

  • 我调试同一个问题超过 2 小时。这是纯粹的邪恶。几乎和#define true false一样邪恶。
【解决方案2】:

这个:

ios_base::open_mode Mode = std::ios_base::in | std::ios_base::binary;

应该是:

std::ios_base::openmode Mode = std::ios_base::in | std::ios_base::binary;

注意openmode 中缺少_

(我必须添加这些行并将您的代码放入一个函数中以使您的 sn-p 编译。

#include <string>
#include <fstream>

using std::string;
using std::ofstream;
using std::ios_base;

)

【讨论】:

    【解决方案3】:

    g++ 不完全符合,但这不是这里出错的原因。

    模式的类型应该是

    std::ios_base::openmode
    

    而不是

    std::ios_base::open_mode
    

    后者是一个旧的、已弃用的 API。在C++标准的Annex D中还是有规定的,所以编译器还是要支持的。

    【讨论】: