c++11 - Perfect forwarding to multiple constructors -
i'm happy perfect forwarding in c++11 , want more complicated. it's classic case. have template axis-aligned box class. template argument vector class. have classic constructor, takes 2 vectors:
template <class t> struct base_vec2 { typedef t scalar_type; base_vec2 (t a, t b); // counsruct 2 scalar calues }; template <class t> struct base_vec3 { typedef t scalar_type; base_vec2 (t a, t b, t c); // counsruct 3 scalar calues }; template <class t> struct base_box { typedef typename t::scalar_type scalar_type; t lower, upper; //<! upper , lower point base_box<t> (const t& min, const t& max); }; base_box<base_vec3<float>> box; naturally, 1 may want implement constructor takes n scalar values , pass them lower , upper constructors. came with:
template <class t> struct base_box { ..... template <typename... ts> base_box<t> (scalar_type s1, scalar_type s2, scalar_type s3, scalar_type s4, ts&&... ts) { base_box_construct<t, scalar_type, (4 + sizeof...(ts))/2> _(lower, upper, s1, s2, s3, s4, std::forward<ts>(ts)...); } }; base_box<base_vec2<float>> box(1, 2, 3, 4); base_box<base_vec3<float>> box(1, 2, 3, 4, 5, 6); base_box_construct actual magic:
template <class t, class a> struct base_box_construct<t, a, 2> { template <typename... ts> base_box_construct(t& lower, t& upper, s1, s2, s3, s4, ts&&... ts) { lower = t(a1, a2); upper = t(a3, a4); } }; template <class t, class a> struct base_box_construct<t, a, 3> { template <typename... ts> base_box_construct(t& lower, t& upper, s1, s2, s3, s4, ts&&... ts) { lower = t(s1, s2, s3); upper = t(s4, std::forward<ts>(ts)...); } }; template <class t, class a> struct base_box_construct<t, a, 4> { template <typename... ts> base_box_construct(t& lower, t& upper, s1, s2, s3, s4, ts&&... ts) { lower = t(s1, s2, s3, s4); upper = t(std::forward<ts>(ts)...); } }; it's bit tricky, since works 2, 3 , 4 arguments per vector need. wondering if there better way implement it.
you can use uniform initialization, no further changes required:
base_box<base_vec3<float>> box { { 1,2,3 }, { 4,5,6 } }; the standard in similar ways using std::piece_wise_construct_t
template <class t> struct base_vec2 { typedef t scalar_type; t a, b; base_vec2 (t a, t b) : a(a), b(b) {} // construct 2 scalar calues }; template <class t> struct base_vec3 { typedef t scalar_type; t a, b, c; base_vec3 (t a, t b, t c) : a(a), b(b), c(c) {} // construct 3 scalar calues }; template <class t> struct base_box { typedef typename t::scalar_type scalar_type; t lower, upper; //<! upper , lower point base_box<t> (const t& min, const t& max) : lower(min), upper(max) { } }; int main() { base_box<base_vec3<float>> box { { 1,2,3 }, { 4,5,6 } }; }
Comments
Post a Comment