【问题标题】:Perfect forwarding to multiple constructors完美转发给多个构造函数
【发布时间】:2015-06-05 09:53:42
【问题描述】:

我对 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 个参数,这正是我所需要的。但我想知道是否有更好的方法来实现它。

【问题讨论】:

    标签: c++11 constructor perfect-forwarding


    【解决方案1】:

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

    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 } };
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多