#include <utility> // move
#include <iostream>
using std::move;
using std::ostream;
struct Matrix {
int d; /* = 0, not yet implemented in gcc-4.7.0 */
Matrix(int e) : d{e} {}
// construction, copy, assign
Matrix() = default;
Matrix(const Matrix&) = default;
Matrix& operator=(const Matrix&) = default;
// move, move-assign (no no magic in this example)
Matrix(Matrix&&) = default;
//Matrix& operator=(Matrix&&) = default;
Matrix& operator=(Matrix&& o) { swap(*this,o); return *this; };
// friendly STL helper
friend void swap(Matrix& a, Matrix& b) /* noexcept */ { std::swap(a.d, b.d); }
// imm ops
void operator+=(const Matrix& o) { d+=o.d; }
void operator*=(const Matrix& o) { d*=o.d; }
// 2ary ops
friend Matrix operator+(const Matrix &a, Matrix &&b ) { b+=a; return move(b); }
friend Matrix operator+(Matrix &&a, const Matrix &b) { a+=b; return move(a); }
friend Matrix operator+(const Matrix &a, Matrix v) { v+=a; return v; }
friend Matrix operator+(Matrix &&a, Matrix &&b) { a+=b; return move(a); }
friend Matrix operator*(const Matrix &a, Matrix &&b ) { b*=a; return move(b); }
friend Matrix operator*(Matrix &&a, const Matrix &b) { a*=b; return move(a); }
friend Matrix operator*(const Matrix &a, Matrix v) { v*=a; return v; }
friend Matrix operator*(Matrix &&a, Matrix &&b) { a*=b; return move(a); }
// demo helper
friend ostream& operator<<(ostream&os, const Matrix& m)
{ return os << m.d; }
};
int main()
{
Matrix a{2},b{3},c{4},d{5};
Matrix x = a*b + c*d; // 2*3+4*5 = 6+20 = 26
std::cout << x << std::endl;
}
I2luY2x1ZGUgPHV0aWxpdHk+IC8vIG1vdmUKI2luY2x1ZGUgPGlvc3RyZWFtPgoKdXNpbmcgc3RkOjptb3ZlOwp1c2luZyBzdGQ6Om9zdHJlYW07CgpzdHJ1Y3QgTWF0cml4IHsKICAgIGludCBkOyAvKiA9IDAsIG5vdCB5ZXQgaW1wbGVtZW50ZWQgaW4gZ2NjLTQuNy4wICovCiAgICBNYXRyaXgoaW50IGUpIDogZHtlfSB7fQoKLy8gY29uc3RydWN0aW9uLCBjb3B5LCBhc3NpZ24KICAgIE1hdHJpeCgpID0gZGVmYXVsdDsKICAgIE1hdHJpeChjb25zdCBNYXRyaXgmKSA9IGRlZmF1bHQ7CiAgICBNYXRyaXgmIG9wZXJhdG9yPShjb25zdCBNYXRyaXgmKSA9IGRlZmF1bHQ7CgovLyBtb3ZlLCBtb3ZlLWFzc2lnbiAobm8gbm8gbWFnaWMgaW4gdGhpcyBleGFtcGxlKQogICAgTWF0cml4KE1hdHJpeCYmKSA9IGRlZmF1bHQ7CiAgICAvL01hdHJpeCYgb3BlcmF0b3I9KE1hdHJpeCYmKSA9IGRlZmF1bHQ7CiAgICBNYXRyaXgmIG9wZXJhdG9yPShNYXRyaXgmJiBvKSB7IHN3YXAoKnRoaXMsbyk7IHJldHVybiAqdGhpczsgfTsKCi8vIGZyaWVuZGx5IFNUTCBoZWxwZXIKICAgIGZyaWVuZCB2b2lkIHN3YXAoTWF0cml4JiBhLCBNYXRyaXgmIGIpIC8qIG5vZXhjZXB0ICovIHsgc3RkOjpzd2FwKGEuZCwgYi5kKTsgfQoKLy8gaW1tIG9wcwogICAgdm9pZCBvcGVyYXRvcis9KGNvbnN0IE1hdHJpeCYgbykgeyBkKz1vLmQ7IH0KICAgIHZvaWQgb3BlcmF0b3IqPShjb25zdCBNYXRyaXgmIG8pIHsgZCo9by5kOyB9CgovLyAyYXJ5IG9wcwogICAgZnJpZW5kIE1hdHJpeCBvcGVyYXRvcisoY29uc3QgTWF0cml4ICZhLCBNYXRyaXggJiZiICAgICApIHsgYis9YTsgcmV0dXJuIG1vdmUoYik7IH0KICAgIGZyaWVuZCBNYXRyaXggb3BlcmF0b3IrKE1hdHJpeCAmJmEsICAgICAgY29uc3QgTWF0cml4ICZiKSB7IGErPWI7IHJldHVybiBtb3ZlKGEpOyB9CiAgICBmcmllbmQgTWF0cml4IG9wZXJhdG9yKyhjb25zdCBNYXRyaXggJmEsIE1hdHJpeCB2KSAgICAgICAgeyB2Kz1hOyByZXR1cm4gdjsgfQogICAgZnJpZW5kIE1hdHJpeCBvcGVyYXRvcisoTWF0cml4ICYmYSwgICAgICBNYXRyaXggJiZiKSAgICAgIHsgYSs9YjsgcmV0dXJuIG1vdmUoYSk7IH0KCiAgICBmcmllbmQgTWF0cml4IG9wZXJhdG9yKihjb25zdCBNYXRyaXggJmEsIE1hdHJpeCAmJmIgICAgICkgeyBiKj1hOyByZXR1cm4gbW92ZShiKTsgfQogICAgZnJpZW5kIE1hdHJpeCBvcGVyYXRvciooTWF0cml4ICYmYSwgICAgICBjb25zdCBNYXRyaXggJmIpIHsgYSo9YjsgcmV0dXJuIG1vdmUoYSk7IH0KICAgIGZyaWVuZCBNYXRyaXggb3BlcmF0b3IqKGNvbnN0IE1hdHJpeCAmYSwgTWF0cml4IHYpICAgICAgICB7IHYqPWE7IHJldHVybiB2OyB9CiAgICBmcmllbmQgTWF0cml4IG9wZXJhdG9yKihNYXRyaXggJiZhLCAgICAgIE1hdHJpeCAmJmIpICAgICAgeyBhKj1iOyByZXR1cm4gbW92ZShhKTsgfQoKLy8gZGVtbyBoZWxwZXIKICAgIGZyaWVuZCBvc3RyZWFtJiBvcGVyYXRvcjw8KG9zdHJlYW0mb3MsIGNvbnN0IE1hdHJpeCYgbSkKICAgIHsgcmV0dXJuIG9zIDw8IG0uZDsgfQoKfTsKCgppbnQgbWFpbigpCnsKICAgIE1hdHJpeCBhezJ9LGJ7M30sY3s0fSxkezV9OwogICAgTWF0cml4IHggPSBhKmIgKyBjKmQ7IC8vIDIqMys0KjUgPSA2KzIwID0gMjYKCiAgICBzdGQ6OmNvdXQgPDwgeCA8PCBzdGQ6OmVuZGw7Cn0K