【问题标题】:Can't write to ostream in gnu linux c++ error: invalid operands of types ofstream and ‘const char [2]’ to binary ‘operatorCan't write to ostream in gnu linux c++ error: invalid operands of types ofstream and ‘const char [2]’ to binary ‘operator
【发布时间】:2018-01-09 16:01:44
【问题描述】:

无法在 Linux 上编译这个小代码:

#include <fstream>
#include <string>
#include <iostream>
#include <stdio.h>
using namespace std;
int main(){
    char fileName[512];
    sprintf(fileName, "test");
    ofstream iriFile(string(fileName));
    iriFile<<",";
    return 0;
}

我是这样编译的:g++ test.cpp 并且得到了这个:

test.cpp:12:11: 错误:类型的无效操作数 'std::ofstream(std::__cxx11::string) {aka std::basic_ofstream(std::__cxx11::basic_string)}' 和 ‘const char [2]’ 转二进制 ‘operator

可能是什么原因?

【问题讨论】:

  • ofstream iriFile(string(fileName)); 是一个函数声明,请参见 Most Vexing Parse。现在没有时间寻找最好的欺骗,但一般来说,编译器可以警告你。 wandbox.org/permlink/tgimOpyhXGcD1Spu
  • 那是很多轮子旋转;就说ofstream iriFile("test");
  • SO 中有不少关于最令人头疼的解析的帖子。见stackoverflow.com/search?q=%5Bcpp%5D+most+vexing+parse。问题的症结在于ofstream iriFile(string(fileName));被解析为ofstream iriFile(string fileName);,这只是一个函数声明。
  • 如果您无法找出错误,通常值得同时使用 GCC 和 Clang 进行测试:警告:括号作为函数声明已消除歧义 [-Wvexing-parse]

标签: c++ linux c++11 fstream


【解决方案1】:

好的,解决办法是去掉隐式的string()创建:

string sFileName(fileName)
ofstream iriFile(sFileName);

【讨论】:

  • 我认为您的意思是“显式”字符串创建。
  • 只需按原样传递它,无需进行不必要的讨厌转换,如果您想安全使用 C++ cast,而不是 C
【解决方案2】:

首先,您不需要将const char * 显式转换为std::string,它有std::ifstream 构造函数:

 std::ofstream iriFile(fileName);

但如果您想更加安全和详细地使用适当的 C++,那么:

std::ofstream iriFile( static_cast<std::string>(fileName) );

不是 C 风格的演员。

【讨论】:

    【解决方案3】:

    正如您所指出的,删除显式字符串创建可以修复它。

    值得补充的是,对于具有explicit 构造函数的类型,也可以通过使用list initialization 来修复此问题,如下所示:

    ofstream iriFile(string{sFileName});
    

    【讨论】:

    • 这是因为我不是以英语为母语的人,像explicitimplicit 这样的词让我有点困惑。所以我只是复制了这个词,因为我认为这就是我想说的。我会改正的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-02
    • 2017-08-02
    • 1970-01-01
    • 1970-01-01
    • 2019-10-05
    • 1970-01-01
    • 2021-01-08
    相关资源
    最近更新 更多