I implemented a tagged union using a class containing an anonymous union and a tag:
class LogFile
{
public:
LogFile(std::ostream& stdStream);
LogFile(std::ofstream fileStream);
LogFile(LogFile&& logFile);
~LogFile();
std::ostream& getStream();
private:
enum { STD_STREAM, FILE_STREAM } streamType_;
union
{
std::ostream *stdStream_;
std::ofstream fileStream_;
};
};
I have trouble implementing the move constructor. In the overloaded "normal" constructors I know which union member to initialize:
LogFile::LogFile(std::ofstream fileStream)
: streamType_(FILE_STREAM), fileStream_(std::move(fileStream))
{
}
But in the move constructor, how do I know which of stdStream_
or fileStream_
I have to initialize. I can't check the value of streamType_
in the initializer list.
std::ostream
pointer or ref to avoid the union. – Vivaciousstd::variant
and let it do all the thinking for you. – Irritationstd::variant
is too new for my taste and not yet supported by my compiler. In my particular case I ended up using astd::unique_ptr<std::ostream>
as suggested by @Rakete1111. For stdout you need to create a new instance ofstd::ostream
on the heap with the underlying buffer ofstd::cout
:std::unique_ptr<std::ostream>(new std::ostream(std::cout.rdbuf()))
(otherwisestd::unique_ptr
would try to delete the statically allocatedstd::cout
) – Liven