D = A + B + C;
//: C05:MyVector.cpp // Optimizes away temporaries via templates. #include <cstddef> #include <cstdlib> #include <ctime> #include <iostream> using namespace std; // A proxy class for sums of vectors template<class, size_t> class MyVectorSum; template<class T, size_t N> class MyVector { T data[N]; public: MyVector<T,N>& operator=(const MyVector<T,N>& right) { for(size_t i = 0; i < N; ++i) data[i] = right.data[i]; return *this; } MyVector<T,N>& operator=(const MyVectorSum<T,N>& right); const T& operator[](size_t i) const { return data[i]; } T& operator[](size_t i) { return data[i]; } }; // Proxy class hold references; uses lazy addition template<class T, size_t N> class MyVectorSum { const MyVector<T,N>& left; const MyVector<T,N>& right; public: MyVectorSum(const MyVector<T,N>& lhs, const MyVector<T,N>& rhs) : left(lhs), right(rhs) {} T operator[](size_t i) const { return left[i] + right[i]; } }; // Operator to support v3 = v1 + v2 template<class T, size_t N> MyVector<T,N>& MyVector<T,N>::operator=(const MyVectorSum<T,N>& right) { for(size_t i = 0; i < N; ++i) data[i] = right[i]; return *this; } // operator+ just stores references template<class T, size_t N> inline MyVectorSum<T,N> operator+(const MyVector<T,N>& left, const MyVector<T,N>& right) { return MyVectorSum<T,N>(left, right); } // Convenience functions for the test program below template<class T, size_t N> void init(MyVector<T,N>& v) { for(size_t i = 0; i < N; ++i) v[i] = rand() % 100; } template<class T, size_t N> void print(MyVector<T,N>& v) { for(size_t i = 0; i < N; ++i) cout << v[i] << ' '; cout << endl; } int main() { srand(time(0)); MyVector<int, 5> v1; init(v1); print(v1); MyVector<int, 5> v2; init(v2); print(v2); MyVector<int, 5> v3; v3 = v1 + v2; print(v3); MyVector<int, 5> v4; // Not yet supported: //! v4 = v1 + v2 + v3; } ///:~
Listado 6.55. C05/MyVector.cpp
v1 = v2 + v3; // Add two vectors
v3.operator=<int,5>(MyVectorSum<int,5>(v2, v3));
v4 = v1 + v2 + v3;
(v1 + v2) + v3;
//: C05:MyVector2.cpp // Handles sums of any length with expression templates. #include <cstddef> #include <cstdlib> #include <ctime> #include <iostream> using namespace std; // A proxy class for sums of vectors template<class, size_t, class, class> class MyVectorSum; template<class T, size_t N> class MyVector { T data[N]; public: MyVector<T,N>& operator=(const MyVector<T,N>& right) { for(size_t i = 0; i < N; ++i) data[i] = right.data[i]; return *this; } template<class Left, class Right> MyVector<T,N>& operator=(const MyVectorSum<T,N,Left,Right>& right); const T& operator[](size_t i) const { return data[i]; } T& operator[](size_t i) { return data[i]; } }; // Allows mixing MyVector and MyVectorSum template<class T, size_t N, class Left, class Right> class MyVectorSum { const Left& left; const Right& right; public: MyVectorSum(const Left& lhs, const Right& rhs) : left(lhs), right(rhs) {} T operator[](size_t i) const { return left[i] + right[i]; } }; template<class T, size_t N> template<class Left, class Right> MyVector<T,N>& MyVector<T,N>:: operator=(const MyVectorSum<T,N,Left,Right>& right) { for(size_t i = 0; i < N; ++i) data[i] = right[i]; return *this; } // operator+ just stores references template<class T, size_t N> inline MyVectorSum<T,N,MyVector<T,N>,MyVector<T,N> > operator+(const MyVector<T,N>& left, const MyVector<T,N>& right) { return MyVectorSum<T,N,MyVector<T,N>,MyVector<T,N> > (left,right); } template<class T, size_t N, class Left, class Right> inline MyVectorSum<T, N, MyVectorSum<T,N,Left,Right>, MyVector<T,N> > operator+(const MyVectorSum<T,N,Left,Right>& left, const MyVector<T,N>& right) { return MyVectorSum<T,N,MyVectorSum<T,N,Left,Right>, MyVector<T,N> > (left, right); } // Convenience functions for the test program below template<class T, size_t N> void init(MyVector<T,N>& v) { for(size_t i = 0; i < N; ++i) v[i] = rand() % 100; } template<class T, size_t N> void print(MyVector<T,N>& v) { for(size_t i = 0; i < N; ++i) cout << v[i] << ' '; cout << endl; } int main() { srand(time(0)); MyVector<int, 5> v1; init(v1); print(v1); MyVector<int, 5> v2; init(v2); print(v2); MyVector<int, 5> v3; v3 = v1 + v2; print(v3); // Now supported: MyVector<int, 5> v4; v4 = v1 + v2 + v3; print(v4); MyVector<int, 5> v5; v5 = v1 + v2 + v3 + v4; print(v5); } ///:~
Listado 6.56. C05/MyVector2.cpp
v4 = v1 + v2 + v3;
v4.operator+(MVS(MVS(v1, v2), v3));