给定以下使用std :: array的向量类(用于2d,3d或4d向量数学),是否可以定义可变参数构造函数和/或转换构造函数?
作为一个后续问题,这种事情是不是很糟糕?我发现自己需要转换为整数,浮点数和双精度数。
我知道隐式转换会发生,但我的编译器会给我一些警告(我不想让它们一般关闭)。
#include <array>
template<typename T0, size_t S>
class Vec
{
public:
static_assert(S > 1 && S < 5, "vector dimension must be between 2 and 4");
static_assert(std::is_arithmetic<T0>::value, "type must be arithmetic");
std::array<T0, S> v;
Vec() = default;
template<class T1, class T2>
Vec(T1 t1, T2 t2) : v({ static_cast<T0>(t1),
static_cast<T0>(t2) }) {}
template<class T1, class T2, class T3>
Vec(T1 t1, T2 t2, T3 t3) : v({ static_cast<T0>(t1),
static_cast<T0>(t2),
static_cast<T0>(t3) }) {}
template<class T1, class T2, class T3, class T4>
Vec(T1 t1, T2 t2, T3 t3, T4 t4) : v({ static_cast<T0>(t1),
static_cast<T0>(t2),
static_cast<T0>(t3),
static_cast<T0>(t4) }) {}
};
int main(void)
{
auto foo1 = Vec<float, 2>(1, 2);
auto foo2 = Vec<float, 2>(1.0f, 2.0f);
auto foo3 = Vec<float, 2>(1.0, 2.0);
auto foo4 = Vec<float, 2>(1u, 2u);
return 0;
}
答案 0 :(得分:2)
当然有可能。
顺便说一句,在这种情况下你不需要默认的构造函数,因为这个可变参数构造函数更好,它会使你的数组归零......template<typename T0, size_t S>
class Vec
{
public:
static_assert(S > 1 && S < 3, "vector dimension must be between 2 and 4");
static_assert(std::is_arithmetic<T0>::value, "type must be arithmetic");
std::array<T0, S> v;
template <typename ...T>
Vec(T&& ...a) : v{{ static_cast<T0>(std::forward<T>(a))...}}
{}
};
答案 1 :(得分:2)
如果将索引序列添加到类模板中:
template<typename T0, size_t S, typename = std::make_index_sequence<S>>
class Vec;
您可以使用额外的东西来定义两个构造函数:
template<typename T0, size_t S, size_t... Idx>
class Vec<T0, S, std::index_sequence<Idx...>>
{
template <size_t> using ith_T = T0;
...
Vec(ith_T<Idx>... ts)
: v({ts...}) // no cast necessary, they're already T0
{ }
template <typename U,
typename = std::enable_if_t<std::is_convertible<U, T0>::value>
>
Vec(const Vec<U, S>& rhs)
: v({static_cast<T0>(rhs.v[Idx])...})
{ }
...
};
答案 2 :(得分:1)
从您的示例中,我认为提交的值在任何情况下都具有相同的类型。那么,为什么不使用std::initializer_list
?此外,您之前将它们转换为T0
类型,然后将它们传递给内部std::array
,所以也许它值得。实际上你并不关心参数的类型,只要你可以将它们转换为T0
。