### reference collapsing problem

The following code is self explanatory.
I use many container<arithmetic> structures as algebra vectors.
To be algebra vectors `is_densevector<T>::value` must be true (commented for simplicity).
The problem is the reference collapsing thing which use the C1&& = C1&& + C2&& instead of C1 = const C1& + const C2&.
Is there any suggestions?
Or something like this (ideally):
 ``1234567`` ``````template C1//typename std::enable_if::value && is_densevector::value, C1>::type &&operator+(C1 &&v1, C2 &&v2) { if (is_rvalue(v1)) ....; else if (is_lvalue(v1)) ....; }``````

Here the complete code:
 ``123456789101112131415161718192021222324252627282930313233`` ``````#include #include #include using namespace std; template void add(C1 &v1, const C2 &v2) { cout << "add(v1,v2)" << endl; } template void add(C1 &v1, const C2 &v2, const C3 &v3) { cout << "add(v1,v2,v3)" << endl; } template C1//typename std::enable_if::value && is_densevector::value, C1>::type &operator+=(C1 &v1, const C2 &v2) { cout << "v1 += v2 : "; add(v1, v2); return v1; } template C1//typename std::enable_if::value && is_densevector::value, C1>::type operator+(const C1 &v1, const C2 &v2) { cout << "C1 = const C1& + const C2& : "; C1 r; add(r, v1, v2); return r; } template C2//typename std::enable_if::value && is_densevector::value, C2>::type &&operator+(const C1 &v1, C2 &&v2) { cout << "C2&& = const C1& + C2&& : "; return v2 += v1; } template C1//typename std::enable_if::value && is_densevector::value, C1>::type &&operator+(C1 &&v1, const C2 &v2) { cout << "C1&& = C2&& + const C2& : "; return v1 += v2; } template C1//typename std::enable_if::value && is_densevector::value, C1>::type &&operator+(C1 &&v1, C2 &&v2) { cout << "C1&& = C1&& + C2&& : "; return v1 += v2; } int main() { std::array ar1{1,2,3}; std::vector ar2{3,2,1}; ar1 + ar2; return 0; }``````
Is it actually that important? In this case I'd say just allow the compiler to properly optimize the code.
Yes it is.
`ar1 + ar2` must call C1 = const C1& + const C2& because ar1,ar2 are lvalues.
Calling the C1&& = C1&& + C2&& leads to destruction of ar1 so later it cannot be used.
If I want to not use ar1, I prefer to write: `std::move(ar1) + ar2` (or `ar1 += ar2`)
And of-course move semantics in containers is a must.
Last edited on
Topic archived. No new replies allowed.