Reputation: 586
Given the following error:
class B {
private:
int n;
public:
B(int x) :
n(x) {
}
B operator+(B& b) {
return B(n + b.n);
}
friend ostream& operator<<(ostream &out, const B& b) {
out << "B: " << b.n;
return out;
}
bool operator<(const B& rhs) const {
return n < rhs.n;
}
};
int main() {
B b1(2);
B b2(3);
B res121 = b1 + (b2 + b1); // ----error
B res21 = b2 + b1;
B res1_21 = b1 + res21; // ---- No error
cout << res1_21;
return 0;
}
Why I get error while I try to define res121
but don't get error while I try to define res1_21
?
After all, b2+b1
is object in type of B
, so what is the problem? What it's say that it's a temporary object
, how can I know what is temporary object
and what it's not.
Upvotes: 3
Views: 92
Reputation: 275405
A temporary object in C++ terminology is an object with no name or identity that comes into existence, usually as the return value of a function. How they work exactly changes between c++11 and c++17.
Their existence ends at the end of the current full expression (usually a ;
), and they cannot bind to non-const
lvalue references, so B&
cannot bind to a temporary.
This:
B operator+(B& b) {
return B(n + b.n);
}
is a poor operator+
. The best1 way to write operator+
is:
B& operator+=(B const& b)& {
n += b.n;
return *this;
}
friend B operator+(B lhs, B const& rhs) {
lhs += rhs;
return lhs;
}
where you implement +=
as a member function, then write a slightly asymmetric friend
operator+
that is implemented in terms of +=
.
The assymetry in +
makes long chains of +
expressions slightly more efficient, especially if you implement cheap-to-move objects.
1 Naturally there are situations where this isn't the best. Like sometimes real expression templates. But you should start with this and only get more complex if you prove you need it.
Upvotes: 10