Sorry in advance for the bad title, not sure what to call what I'm trying to do.
Some background, if you don't care to read, skip to the next paragraph. I have a unit test class where I call assert with some condition and if it fails I output some string that was passed in. I have found that it is quite annoying to build a string to send to this if for instance I want to say "Failed on index: " + i
. My idea is to return a std::ostream
instead of taking a std::string
. If the assert fails I return std::cerr
, if the assert passes then I return a std::stringstream
. I imagine I could do all of this just fine. I'd have to store a std::stringstream
in my unit test class so I can return a reference.
What I would like to do is instead of returning a standard std::ostream
return an extended std::ostream
that outputs std::endl
when it's done so I don't have to remember it for each assert. In particular the idea is the following:
UnitTest("My test");
ut.assert(false) << "Hello world";
ut.assert(1 == 0) << "On the next line";
The idea being that on destruction this new class would output the endline and that it would be destructed as soon as it was no longer used (i.e. no more << operators). So far this is what I have (I've removed some of the code in assert, and it's actually inside a class, but this is sufficient to show what's going on):
class newline_ostream : public std::ostream
{
public:
newline_ostream(std::ostream& other) : std::ostream(other.rdbuf()){}
~newline_ostream() { (*this) << std::endl; }
};
newline_ostream& assert(bool condition, std::string error)
{
if(!condition)
{
return newline_ostream(std::cerr);
}
return newline_ostream(std::stringstream());
}
When I try this method I get some stuff basically telling me that returning an object I just created is wrong because it's not an lvalue. When I try changing it to not return a reference it complains that there's no copy constructor (presumably this is because I'm extending std::ostream
and it doesn't have a copy constructor).
What I'm looking for is some method that causes the compiler to create a temporary newline_ostream that assert()
will write it's result into that will die as soon as it's no longer used (i.e. no more << operators). Is this possible and if so how?