Reputation: 13575
Does the ternary operation return a copy or reference?
I checked the following code
vector<int> v0 = { 1, 2 };
vector<int> v1 = { 3 };
vector<int>& v = true ? v0 : v1;
v.clear(); // v0 will be cleared also
I think the ternary operation returns a copy of v0
. And then pass it to v
. Thus v
and v0
has different storage of data. Testing doesn't show it.
Thanks, Kerrek SB! I add a "should-not-compiled" example (Thanks WhiZTiM!) to show the point.
vector<int>& v = true ? v0 : vector<int>{3};
v.clear(); // v0 will not be cleared
Upvotes: 7
Views: 270
Reputation: 21576
The rules are found here: Relevant to your expression:
E1 ? E2 : E3
4) If E2 and E3 are glvalues of the same type and the same value category, then the result has the same type and value category, and is a bit-field if at least one of E2 and E3 is a bit-field.
In your case:
true ? v0 : v1;
v0
and v1
are lvalues (broadly glvalue).
So the return will be an lvalue v0
. Hence, your expression will be equivalent to:
vector<int>& v = v0;
As to your Edit:
vector<int>& v = true ? v0 : vector<int>{3};
v.clear(); // v0 will not be cleared
Should not compile, because the value category of the result will be an rvalue
, and you cannot bind a non-const reference to an rvalue
Upvotes: 3
Reputation: 477110
The type of a conditional expression is the common type of the operands.
But I think you aren't actually interested in that. What matters is what the value category of a conditional expression is.
If both operands are, or can be converted to, lvalues of the common type, then the conditional expression is an lvalue; otherwise it is an rvalue (potentially requiring lvalue-to-rvalue conversion of one of the operands).
Upvotes: 15