Reputation: 1149
#include <iostream>
#include <fstream>
class A {
private:
std::ostream&& out;
public:
A(std::ostream&& o) : out(std::move(o)) {
out.write("test", 4);
}
void writeTest2() {
out.write("test2", 5);
out.flush(); // still does nothing.
}
};
int main() {
A a{std::ofstream{"testic"}};
a.writeTest2();
}
When the above code is run, it creates a file named testic
as expected. However, the file created contains test
but not testtest2
, which is obviously unexpected. What exactly is causing this behavior?
When std::ostream
is taken as a lvalue reference it functions perfectly as intended.
Additional information
clang
, gcc
.Upvotes: 0
Views: 80
Reputation: 96845
The temporary std::ofstream{"testic"}
that you created only exists for the duration of the constructor call. After that it is destroyed and the file is closed, which means you are left with a reference that refers to garbage. Using that reference results in undefined behavior.
To fix it you can remove the reference all together (the &&
from std::ostream&& out
and std::ostream&& o
) and have it create a new object that is initialized from the temporary.
The above won't work because std::ostream
cannot be moved. You will have to use a pointer instead if you want to maintain polymorphism. If that isn't important you can change all std::ostream&&
to std::ofstream
:
class A {
private:
std::unique_ptr<std::ostream> out;
public:
A(std::unique_ptr<std::ostream> o) : out(std::move(o)) {
out->write("test", 4);
}
void writeTest2() {
out->write("test2", 5);
out->flush();
}
};
int main() {
A a{std::make_unique<std::ofstream>("testic")};
a.writeTest2();
}
Upvotes: 3