提问者:小点点

如果模板为整数类型,则仅对某些模板规范启用函数


我有一个Vector类,它有一个的模板,例如。我可以为二维空间中的向量执行vector<2>,为四维空间执行vector<4>等等。如果dim==specific value,我想在类中添加一些方法,例如crossproductvector<3>执行x,y,z,wgetters为一个足够维的向量执行x,y,z,w。如果与维度不正确的向量一起使用,我希望得到一个编译错误。

我到处看了很多,其中一个我认为比较接近的东西是std::enable_if,但是,我不知道如何在我的特定情况下使用它(条件是dim==xdim>x)。

这是正确的方式,还是有一个完全不同的方式我应该做这件事?

顺便说一下,我使用的是C++17。


共2个答案

匿名用户

>

  • 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)用于方法主体的其余部分,如果需要不同的实现,则可以基于当前维度“专门化”代码。