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