我有一个Vector类,它有一个
的模板,例如。我可以为二维空间中的向量执行vector<2>
,为四维空间执行vector<4>
等等。如果dim==specific value
,我想在类中添加一些方法,例如crossproduct
为vector<3>
执行x,y,z,w
getters为一个足够维的向量执行x,y,z,w
。如果与维度不正确的向量一起使用,我希望得到一个编译错误。
我到处看了很多,其中一个我认为比较接近的东西是std::enable_if
,但是,我不知道如何在我的特定情况下使用它(条件是dim==x
或dim>x
)。
这是正确的方式,还是有一个完全不同的方式我应该做这件事?
顺便说一下,我使用的是C++17。
>
C++20之前,static_assert
可能是最简单的:
template <std::size_t Dims>
struct Vector
{
// ...
double getZ() const { static_assert(Dims >= 3); return data[2]; }
};
SFINAE是可能的,但复杂而冗长:
template <std::size_t Dims>
struct Vector
{
// ...
template <std::size_t D = Dims, std::enable_if_t<(D >= 3) && D == Dims, int> = 0>
double getZ() const { return data[2]; }
};
专门化是可能的,但可能很棘手,例如:
struct NullVector3{};
template <typename Derived>
struct Vector3
{
// ...
double getZ() const { return static_cast<Derived*>(this)->data[2]; }
};
template <std::size_t Dims>
struct Vector : std::conditional_t<(Dims >= 3), Vector3<Vector>, NullVector3> /*, ..*/
{
// ...
// inherit of Vector3<Vector>::getZ() when Dims >= 3
// inherit of no extra method from NullVector3 else.
};
C++20是最简单的要求
:
template <std::size_t Dims>
struct Vector
{
// ...
double getZ() const requires(Dims >= 3) { return data[2]; }
};
我将实现泛型接口的方法并添加
static_assert(dim==3,“此方法仅对三维向量有效。”)
作为每个方法中的第一行。与std::enable_if
方法相比,这将产生更清晰的编译器错误消息。
您还可以将constexpr if(dim==x)
用于方法主体的其余部分,如果需要不同的实现,则可以基于当前维度“专门化”代码。