【问题标题】:Choose fstream or cout depending on attributes根据属性选择 fstream 或 cout
【发布时间】:2025-12-02 19:35:01
【问题描述】:

如果有argv[1],我想将一些数据放入新的ofstream(argv[1]),即名称为argv[1]的文件。但如果没有这样的论点,我想改用cout

我试过了

std::ostream& output = argc >= 1 ? std::fstream(argv[0]) : std::cout;

但由于构造函数被删除,它甚至无法编译。

【问题讨论】:

  • 尝试不要将fstream 设为临时地址。
  • 此外,为什么不直接使用输出重定向呢?我能想到的所有操作系统都支持它,你可以使用cout免费获得它。
  • @zneak: 如果没有 arg ,我如何创建它而不是临时的?
  • 我必须使用允许将文件名放入 args 的接口
  • 您正在尝试获取对临时值的引用,这就是它不起作用的原因。您无法获得对临时值的引用。这就像尝试做double& d = sin(1)

标签: c++ c++11 stream


【解决方案1】:

您可以创建一个 fstream 实例并延迟打开它,直到需要。

std::fstream file;
if (argc > 1)
    file.open(argv[1]);

std::ostream& output = argc > 1 ? file : std::cout;

【讨论】:

  • +1 赞成,这是一个很好的、可以理解的解决方案。不过,如果不需要,您可以避免创建fstream,以及轻微的代码重复:在argc>1 上分支两次。看我的回答。
【解决方案2】:

您不能使用具有不同类型的三元运算符。编译器无法决定结果应该是什么类型。

你可以试试

if (argc >= 1)
{
    std::fstream   Output(argv[0]);
    Process_data(Output);
}
else
    Process_data(std::cout);

【讨论】:

  • 我不认为你的第一句话是准确的。
  • @LuchianGrigore 部分正确,但仅当编译器无法将两种类型解析为相同的基本类型时。在这种情况下,std::fstream 继承自 std::ostream,因此它实际上是有效的。
  • 这也可能与创建一个临时绑定到引用有关。流是不可复制的。
  • @BoPersson 缺少const 绝对是一个问题,是的,但不是唯一的问题。
  • @KurtStutsman 是的,我知道。这是一个反例,“但这当编译器无法将这两种类型解析为相同的基本类型时。”
【解决方案3】:

这是一个真正的 C++11 解决方案:

ostream& out = [=]() -> ostream& {
    if (argc>1) {
        static fstream fs(argv[1]);
        return fs;
    }
    return cout;
}();

【讨论】:

  • 我喜欢 C++11,但我不喜欢这个!
  • @JohnZwinck 是的,我赞成接受的答案和 Bo 的答案。
  • @JohnZwinck 在这方面,lambdas 有一点很不错:我可以初始化 const 对象,即使它们的初始化很复杂。我喜欢它!
最近更新 更多