#include #include struct trace { trace() { std::cout << "default ctor\n"; } trace( trace const& ) { std::cout << "copy ctor\n"; } trace& operator=( trace const& ) { std::cout << "copy assign\n"; return *this; } ~trace() { std::cout << "dtor\n"; } friend void swap( trace& x, trace& y ) { std::cout << "swap\n"; } }; template struct assignment { assignment(T& lhs) : lhs(lhs) {} template T& operator=(U& lvalue) { return lhs = lvalue; } struct ref { ref(T const& mutable_rvalue) : m(const_cast(mutable_rvalue)) { } T& m; }; T& operator=(ref x) { swap(lhs, x.m); return lhs; } T& lhs; }; template assignment assign(T& x) { return assignment(x); } trace const const_rvalue() { return trace(); } int main() { trace x; trace dst; std::cout << "=== rvalue ===\n"; assign(dst) = trace(); std::cout << "=== const rvalue ===\n"; assign(dst) = const_rvalue(); std::cout << "=== lvalue ===\n"; assign(dst) = x; std::cout << "=== const lvalue ===\n"; trace const& y = x; assign(dst) = y; std::cout << "=== done ===\n"; }