为什么我不能在同一个代码行中创建和打开一个 ofstream?

Why I cannot create and open an ofstream in the same code line?

我能做到:

std::ofstream outfile; outfile.open("foo");

但不是:

std::ofstream outfile.open("foo");

因为它给出了这个错误:

error: expected ';' at end of declaration
    std::ofstream outfile.open("foo");
                         ^

正如您在 Live Demo.

中看到的那样

为什么?

PS:我知道我可以 std::ofstream outfile("foo");,但我怀疑我缺少 C++ 的机制,这就是我问的原因。

Why?

因为该语言不允许将声明与成员函数调用结合起来。变量 outfile 甚至在声明之后才存在。

使用构造函数打开文件:

std::ofstream outfile("foo");

but not:

std::ofstream outfile.open("foo");

这是一个简单明了的语法错误。此时,outfile 被解释为某个未定义对象的名称。编译器根本不理解你想创建一个 ofstream.

类型的对象

我们可能天真地希望我们可以像这样简单地修复它:

auto outfile = std::ofstream().open("foo"); // call open on a constructed object.

问题是方法 open 没有 return ofstream 的副本,所以这行不通。 (实际上 return 无效)。

有用的东西:

// unexciting, but simple - uses a different constructor
std::ofstream outfile{"foo"};

这(恕我直言)更具可读性和合法性:

auto outfile = std::ofstream("foo");

你可以这样做:

std::ofstream outfile { "foo" };

因为语言。 C++ 不允许这样的指令。

使用构造函数

std::ofstream outfile("foo");

或初始化

std::ofstream outfile { "foo" };

这类似于当你有一个函数 return 是一个对象并且你想在同一行中调用它的方法时:

struct foo { void bar(){} };
foo create_foo() { return foo(); }

您可以存储 create_foo 的结果或使用它的 return 值来调用方法,但不能同时使用:

create_foo().bar();          // OK
auto f = create_foo();       // OK
auto f = create_foo().bar(); // NOPE

回到ofstream:你可以写

std::ofstream().open("foo");

但您没有机会获得对 ofstream 的引用。

我猜您已经习惯了 Java 或 C# 之类的东西,在这种情况下可能会出现这种情况:

BufferedReader br = new BufferedReader(new FileReader(FILENAME));

甚至 Python:

lines = open("filename").readlines();

这里的诀窍是,使用正确的 "factory functions",您也可以在 C++ 中执行此操作,但这不是特定 class 的制作方式。上面的其他示例,其中任何一个:

std::ofstream outfile{"foo"};
auto outfile = std::ofstream("foo");

是 C++ 中的 "normal" 方式。断开连接的部分原因是 open() 方法 returns void: std::basic_ofstream::open() doc。所以当你有这个代码时:

std::ofstream outfile.open("foo");

它无法编译,因为 open() 是一个成员函数(不是静态的)并且它 returns void 不是 std::ofstream,这是你声明的重新制作。

我希望这能帮您解决问题。

因为你做不到。

说真的。

C++ 具有允许的语法,您不得编写不符合它的代码。

declaration/expression 混合体在尚不存在的对象上使用 void 返回成员函数且没有 = 初始化程序的用例为零.

但你已经知道了。