c++ - Data members as lvalue-reference or rvalue-copies -
consider following struct template:
template<typename t> struct x { x(t t) : t(std::forward<t>(t)) {} t t; };
where t either lvalue-reference (e.g, const int&
) or regular value (e.g, int
). idea use lvalue-reference whenever x
constructed lvalue, , regular value when constructed rvalue.
therefore, following factory functions defined create instance of x
such properties:
template<typename t> x<const t&> createx(const t& val) { return x<const t&>(val); } template<typename t> typename std::enable_if<std::is_rvalue_reference<t&&>::value, x<t>>::type createx(t&& val) { return x<t>(std::move(val)); }
so far, good. if consider struct template y
:
template<typename t, typename u> struct y { y(t t, u u) : t(std::forward<t>(t)), u(std::forward<t>(u)) {} t t; u u; };
and decide make same analogy before x
, end these 4 factory functions:
template<typename t, typename u> y<const t&, const u&> createy(const t& t, const u& u) { return y<const t&, const t&>(t, u); } template<typename t, typename u> typename std::enable_if<std::is_rvalue_reference<t&&>::value, y<t, const u&>>::type createy(t&& t, const u& u) { return y<t, const u&>(std::forward<t>(t), u); } template<typename t, typename u> typename std::enable_if<std::is_rvalue_reference<u&&>::value, y<const t&, u>>::type createy(const t& t, u&& u) { return y<const t&, u>(t, std::forward<t>(u)); } template<typename t, typename u> typename std::enable_if<std::is_rvalue_reference<t&&>::value , std::is_rvalue_reference<u&&>::value, y<t, u>>::type createy(t&& t, u&& u) { return y<t, u>(std::forward<t>(t), std::forward<t>(u)); }
is there alternative way obtain same result, perhaps less verbose? fortunately application not require more 2 template data members, several other classes y
needed, requiring 4 factory functions each of them.
this results in non-const lvalue-references when constructed lvalues, , them const lvalue-references
you can write simple trait transforms lvalue references:
template<class t> struct transform_parameter{ using type = t; }; template<class t> struct transform_parameter<t&>{ using type = t const&; }; template<class t> using transformparameter = typename transform_parameter<t>::type;
and apply relevant template parameters:
template<class t> x<transformparameter<t>> make_x(t&& v){ return {std::forward<t>(v)}; }
i used braced-init-list (aka uniform initialization) here save me writing type twice.
Comments
Post a Comment