c++ - Universal reference with templated class -


example:

template <typename t> class bar { public:     void foo(t&& arg)     {         std::forward<t>(arg);     } };  bar<int> bar;      bar.foo(10); // works  int a{ 10 }; bar.foo(a); // error c2664: cannot convert argument 1 'int' 'int &&' 

it seems universal references works only templated functions , only type deduction, right? make no sense use class? , using of std::forward makes sense in case?

note preferred terminology (i.e. 1 in future versions of spec) forwarding reference.

as say, forwarding reference works type deduction in function template. in case, when t&&, t int. can't int& because has been explicitly stated in bar instantiation. such, reference-collapsing rules can't occur, can't perfect forwarding.

if want perfect forwarding in member function that, need have member function template:

template <typename u> void foo(u&& arg) {     std::forward<u>(arg); //actually here } 

if absolutely need u have same unqualified type t, can static_assert:

template <typename u> void foo(u&& arg) {     static_assert(std::is_same<std::decay_t<u>,std::decay_t<t>>::value,                    "u must same t");     std::forward<u>(arg); //actually here } 

std::decay might bit aggressive decay array types pointers. if that's not want, write own simple trait:

template <typename t> using remove_cv_ref = std::remove_cv_t<std::remove_reference_t<t>>;  template <typename t, typename u> using is_equiv = std::is_same<remove_cv_ref<t>, remove_cv_ref<u>>; 

if need variadic version, can write are_equiv trait. first need trait check if traits in pack true. i'll use bool_pack method:

namespace detail {     template<bool...> struct bool_pack;     template<bool... bs>     using all_true = std::is_same<bool_pack<bs..., true>, bool_pack<true, bs...>>; } template <typename... ts> using all_true = detail::all_true<ts::value...>; 

then need check if each pair of types in ts... , us... satisfy is_equiv. can't take 2 parameter packs template arguments, i'll use std::tuple separate them (you use sentinel node, or split pack halfway through instead if wanted):

template <typename ttuple, typename utuple> struct are_equiv;  template <typename... ts, typename... us> struct are_equiv <std::tuple<ts...>, std::tuple<us...>> : all_true<is_equiv<ts,us>...> {}; 

then can use like:

static_assert(are_equiv<std::tuple<ts...>,std::tuple<us...>>::value,                "us must equivalent ts"); 

Comments

Popular posts from this blog

angularjs - ADAL JS Angular- WebAPI add a new role claim to the token -

php - CakePHP HttpSockets send array of paramms -

node.js - Using Node without global install -