#include //Comment this to use ref_holder //instead of std::tr1::tuple //to pack argument references #define USE_TUPLE #ifdef USE_TUPLE #include #endif //forward declaration of function "func" //simulates an #include<> template void func(Args && ...args); //////////////////////////////////////////////////// // Move and forward implementation //////////////////////////////////////////////////// template struct remove_reference { typedef T type; }; template struct remove_reference { typedef T type; }; // identity is an extension: it is not part of the standard. template struct identity { typedef T type; }; template inline typename remove_reference::type&& move_impl(T&& t) { return t; } template inline T&& forward_impl(typename identity::type&& t) { return t; } #ifndef USE_TUPLE //////////////////////////////////////////////////// // ref_holder is a class that packs the arguments // forwarded to a variadic function // // ref_holder behaves similart to tuple //////////////////////////////////////////////////// template class ref_holder; //This is the implementation of the holder template struct ref_holder_impl; template struct ref_holder_impl {}; template struct ref_holder_impl : public ref_holder_impl { typedef ref_holder_impl Base; Head &&head_; explicit ref_holder_impl(Head &&head, Tail&&... tail) : Base(tail...), head_(head) {} }; template class ref_holder : public ref_holder_impl<0, Args...> { typedef ref_holder_impl<0, Args...> Base; public: ref_holder() : Base() {} explicit ref_holder(Args&&... args) : Base(args...) {} }; template<> class ref_holder<> {}; /////////////////////////////////////// // Returns the type of the ith reference // Similar to get<> function of tuples /////////////////////////////////////// template struct get_ref_type; template struct get_ref_type > : get_ref_type > {}; template struct get_ref_type<0, ref_holder > { typedef Head&& type; }; template inline Head &&get_ref_impl(ref_holder_impl& t) { return t.head_; } template inline Head &&get_ref_impl(const ref_holder_impl& t) { return t.head_; } template inline typename get_ref_type >::type get_ref(ref_holder& t) { return get_ref_impl(t); } template inline typename get_ref_type >::type get_ref(const ref_holder& t) { return get_ref_impl(t); } #endif //#ifndef USE_TUPLE //////////////////////////////////////////////////// // Builds an index_tuple<0, 1, 2, ..., Num-1>, that will // be used to "unpack" a ref_holder into comma-separated values // in a function call. See "forward_obj::operator()()" //////////////////////////////////////////////////// template struct index_tuple{}; template > struct build_number_seq; template struct build_number_seq > : build_number_seq > {}; template struct build_number_seq<0, index_tuple > { typedef index_tuple type; }; //////////////////////////////////////////////////// // Implementation of the variadic func // This function prints if passed references are // rvalue or rvalue references //////////////////////////////////////////////////// //This function creates a functor (forward_obj) that perfectly //forwards all parameters to the variadic function "func()" template class forward_obj { public: forward_obj(Args&&... args) : args_(args...) {} void operator()() { //Pass Indexes as an argument so that "call" can get_ref //a variadic list of integers as template arguments this->call(typename build_number_seq::type()); } template void call(const index_tuple&) { //Use the the variadic list of integers to get a //comma-separated list of parameters #ifdef USE_TUPLE func(forward_impl(std::tr1::get(args_))...); #else func(forward_impl(get_ref(args_))...); #endif } private: #ifdef USE_TUPLE std::tr1::tuple args_; #else ref_holder args_; #endif }; /////////////////////////////////////////////////////////////// // This function creates a functor (forward_obj) that perfectly // forwards all parameters to the variadic function "func()" /////////////////////////////////////////////////////////////// template forward_obj forward_func(Args && ...args) { return forward_obj(forward_impl(args)...); } //////////////////////////////////////////////////// // Implementation of the variadic function "func" // This function prints if passed references are // rvalue or lvalue references //////////////////////////////////////////////////// template struct print_rvalue_or_lvalue; template struct print_rvalue_or_lvalue { void operator()() { std::printf("rvalue, "); } }; template struct print_rvalue_or_lvalue { void operator()() { std::printf("lvalue, "); } }; template struct print_rvalue_or_lvalue { void operator()() { std::printf("clvalue, "); } }; //Recursive print object function template struct print; template struct print { void operator()() { print_rvalue_or_lvalue()(); print()(); } }; template<> struct print<> { void operator()() { std::printf("END\n"); } }; template void func(Args && ...args) { print()(); } //////////////////////////////////////////////////// // Non-copyable and non-movable class //////////////////////////////////////////////////// class non_copyable_non_movable { non_copyable_non_movable(const non_copyable_non_movable&); non_copyable_non_movable(non_copyable_non_movable&&); non_copyable_non_movable & operator=(const non_copyable_non_movable&); non_copyable_non_movable & operator=(non_copyable_non_movable&&); public: non_copyable_non_movable(){} }; //////////////////////////////////////////////////// // Test //////////////////////////////////////////////////// int main() { /* This should print: END lvalue, END clvalue, END rvalue, END rvalue, lvalue, clvalue, END lvalue, clvalue, rvalue, END */ non_copyable_non_movable a; const non_copyable_non_movable ca; forward_func()(); forward_func(a)(); forward_func(ca)(); forward_func(move_impl(a))(); forward_func(move_impl(a), a, ca)(); forward_func(a, ca, move_impl(a))(); return 0; }