#include <iostream>
template <typename T>
class fast_arg
{
public:
fast_arg(const T & val)
: lval_(&val), rval_(nullptr) {}
fast_arg(T &&val)
: lval_(nullptr), rval_(&val) {}
template <typename T1>
fast_arg(T1 &&val)
: lval_(nullptr), rval_(nullptr)
{
static T temp(std::forward<T1>(val));
rval_ = &temp;
}
void copy_to(T &target)
{
if (lval_) target = *lval_;
else target = std::move(*rval_);
}
T create_as_copy()
{
if (lval_) return *lval_;
else return std::move(*rval_);
}
private:
const T *lval_;
T *rval_;
};
class logged_creation
{
public:
logged_creation() {std::cout << "def ctor\n";}
logged_creation(int) {std::cout << "int ctor\n";}
logged_creation(const logged_creation &) {std::cout << "copy ctor\n";}
logged_creation(logged_creation &&) {std::cout << "move ctor\n";}
logged_creation& operator = (const logged_creation &) {std::cout << "copy assignment\n";}
logged_creation& operator = (logged_creation &&) {std::cout << "move assignment\n";}
};
template <typename T>
class foo
{
public:
void func(fast_arg<T> val)
{
auto v = val.create_as_copy();
}
};
int main()
{
foo<logged_creation> f;
std::cout << "LValue:\n";
logged_creation i;
f.func(i);
std::cout << "RValue:\n";
f.func(logged_creation());
std::cout << "Converted Temporary:\n";
f.func(42);
}