The TT&&
in Inst(TT &&) {out(3);}
is somewhat special. So, special that there is even a special "term" coined for them called universal reference
.
In short TT&&
is not what you think it is. There are two things that come into play here: Reference Collapsing and Template Deduction
Since TT
is a template parameter and you stuck &&
in front of it, this is what T&&
becomes in your example:
Inst<K> I1{k}; ---> Inst(K&)
Inst<K> I2{kk}; ---> Inst(KK&)
Inst<K> I3{i}; ---> Inst(Inst<K>&)
Inst<K> I4{K()}; ---> Inst(K&&)
Inst<K> I5{KK()} ---> Inst(KK&&)
What happens is TT&&
becomes an exact match and is the selected constructor for all the calls you make, which is why you see 3
for each one (except for i
and I6
).
For further reading, please see: