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