#include <iostream>
using namespace std;

struct A
{
    template<typename T> A(T&&) { cout << "T&&"       << endl; }
    A(A&)                       { cout << "A&"        << endl; }
    A(const A&)                 { cout << "const A&"  << endl; }
    A(A&&)                      { cout << "A&&"       << endl; }
    A(const A&&)                { cout << "const A&&" << endl; }
};

struct B
{
    template<typename T> B(T&&) { cout << "T&&"       << endl; }
    B(B&)                       { cout << "B&"        << endl; }
    B(const B&)                 { cout << "const B&"  << endl; }
    B(B&&)                      { cout << "B&&"       << endl; }
    B(const B&&) = delete;
};

int main() {
    A pi(3.14159);            // T&&
    const A answer(42);       // T&&
    A a1(pi);                 // A&
    A a2(answer);             // const A&
    A a3(std::move(pi));      // A&&
    A a4(std::move(answer));  // const A&&

    B hello("Hello");         // T&&
    const B world("World");   // T&&
    B b1(hello);              // B&
    B b2(world);              // const B&
    B b3(std::move(hello));   // B&&
//  B b4(std::move(world));   // error: const B&& is deleted

    return 0;
}