// g++ -std=c++11 -Wall -Wextra -Wpedantic -o chain chain.cpp #include <iostream> #define DEL(X) \ X = delete; #define DEF(X, ...) \ X \ { \ std::cout << this << " " << #X << std::endl; \ __VA_ARGS__; \ } #define CHAIN(N) \ DEF(S const & N() const &, return *this;) \ DEF(S & N() &, return *this;) \ DEF(S N() &&, return std::move(*this);) // DEF(S && N() &&, return std::move(*this);) struct S { DEF(S(),) DEF(~S(),) DEL(S(S const &)) DEF(S(S &&),) DEL(S & operator=(S const &)) DEF(S & operator=(S &&), return *this;) CHAIN(chain) }; int main() { auto s1 = S{}.chain(); std::cout << &s1 << " " << "use" << std::endl; std::cout << std::endl; auto const & s2 = S{}.chain(); std::cout << &s2 << " " << "use" << std::endl; std::cout << std::endl; auto s3 = S{}; s3.chain(); std::cout << std::endl; auto const s4 = S{}; s4.chain(); std::cout << std::endl; // 0x7ffef298ba3f S() // 0x7ffef298ba3f S chain() && // 0x7ffef298ba3c S(S &&) // 0x7ffef298ba3f ~S() // 0x7ffef298ba3c use // 0x7ffef298ba3f S() // 0x7ffef298ba3f S chain() && // 0x7ffef298ba3d S(S &&) // 0x7ffef298ba3f ~S() // 0x7ffef298ba3d use // 0x7ffef298ba3e S() // 0x7ffef298ba3e S & chain() & // 0x7ffef298ba3f S() // 0x7ffef298ba3f S const & chain() const & // 0x7ffef298ba3f ~S() // 0x7ffef298ba3e ~S() // 0x7ffef298ba3d ~S() // 0x7ffef298ba3c ~S() }