'Modern pattern to write custom ostream operator
Typically, in C++, we used to define a custom ostream operator<<
this way:
class A {
int impl_;
friend std::ostream& operator<<(std::ostream& os, A const& self){
return os << "A:" << self.impl_;
}
};
However now, post C++11, there are r-value references, and as a matter of fact, built-in types can be streamed to r-value std::ostream
references.
Now this is allowed:
int i = 5;
std::ofstream("file") << i;
(I don't know if this is the reason the special overloads were defined.)
Does it mean that for consistency one should define both operators for custom classes? Like this,
class A {
int impl_;
friend std::ostream& operator<<(std::ostream& os, A const& self) {
return os << "A:" << self.impl_;
}
friend std::ostream&& operator<<(std::ostream&& os, A const& self) {
os << "A:" << self.impl_;
return std::move(os);
}
};
or more streamlined,
class A {
int impl_;
friend std::ostream& operator<<(std::ostream& os, A const& self) {
return os << "A:" << self.impl_;
}
friend std::ostream&& operator<<(std::ostream&& os, A const& self) {
return std::move(os << self); // calls the other overload
}
};
What is the recommended way to overload operator<<
nowadays in C++11?
Solution 1:[1]
Besides the conceptual discussion, from a technical viewpoint:
After some experimentation I realized that I don't need to overload for the r-value ostream, the library does it for me already.
One only has to have the l-value version and the library has some r-value version that is forwarded to the implemented overload, which presumably works for any std namespace argument of operator << through ADL or something.
So, in C++11, this is allowed std::ofstream{"file"} << a
, even if no r-value overload (for the stream) is custom defined.
Which seems to make operator<<
quite special in STL.
Corrections are welcome.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |