完美转发到多个构造函数

时间:2015-03-31 21:45:34

标签: c++11 constructor perfect-forwarding

我对C ++ 11中的完美转发非常满意,并希望做一些更复杂的事情。这有点像经典案例。我有一个模板轴对齐框类。模板参数是矢量类。所以我有一个经典的构造函数,需要2个向量:

template <class T> struct base_vec2 {
    typedef T scalar_type;
    base_vec2 (T a, T b); // counsruct for two scalar calues
};
template <class T> struct base_vec3 {
    typedef T scalar_type;
    base_vec2 (T a, T b, T c); // counsruct for three scalar calues
};
template <class T> struct base_box {
    typedef typename T::scalar_type scalar_type;
    T lower, upper; //<! upper and lower point
    base_box<T> (const T& min, const T& max);
};
base_box<base_vec3<float>> box;

当然,人们可能希望实现一个构造函数,它接受n个标量值并将它们传递给下层和上层构造函数。这就是我想出的:

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做真正的魔术:

template <class T, class A>
struct base_box_construct<T, A, 2> {
   template <typename... Ts>
   base_box_construct(T& lower, T& upper, A s1, A s2, A s3, A 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, A s1, A s2, A s3, A 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, A s1, A s2, A s3, A s4, Ts&&... ts)
   {
      lower = T(s1, s2, s3, s4);
      upper = T(std::forward<Ts>(ts)...);
   }
};

这有点棘手,因为它每个向量只能使用2个,3个和4个参数,这正是我所需要的。但我想知道是否有更好的方法来实现它。

1 个答案:

答案 0 :(得分:0)

您可以使用统一初始化,无需进一步更改:

base_box<base_vec3<float>> box { { 1,2,3 }, { 4,5,6 } };

标准使用std::piece_wise_construct_t

以类似方式执行此操作

<强> Live On Coliru

template <class T> struct base_vec2 {
    typedef T scalar_type;
    T a, b;
    base_vec2 (T a, T b) : a(a), b(b) {} // construct for two 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 for three scalar calues
};
template <class T> struct base_box {
    typedef typename T::scalar_type scalar_type;
    T lower, upper; //<! upper and 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 } };
}