首页 > 解决方案 > 是否可以使用带有模板非类型参数的#if 指令?(矢量多合一课)

问题描述

我正在创建一个 Vector 类,而不是创建单独的类,Vector2我想创建一个多合一的类。我的问题是我想根据向量的大小定义某些属性。例如,一个大小的向量将有一个和分量,但没有一个分量。Vector3Vector42xyz

我正在尝试使用该#if指令来检查非类型模板参数 ( SIZE) 以根据向量的大小创建属性。我做了一些研究,我认为这是不可能的。我想知道是否有人知道如何实现我想要的?

template <typename T, int SIZE>
class Vector
{
public:
    union
    {
        struct
        {
#if SIZE == 2
            T x, y;
#endif
#if SIZE == 3
            T z;
#endif
#if SIZE == 4
            T w;
#endif
        };
        T data[SIZE];
    };
};

我希望能够像这样创建和访问 Vector:

Vector<int, 2> vec2;
vec2.x;
Vector<int, 3> vec3;
vec3.z;

任何反馈表示赞赏!

编辑:在查看评论后,我想出了一个漂亮的解决方案......希望它对我有用。我创建了一个模板类:

template <typename T, unsigned int SIZE> class _vec;

这处理向量的数据(组件)并包含行为。然后我制作了另一个模板类,它会_vec像这样专门化:

template <typename T, unsigned int SIZE> class Vector : public _vec<T, SIZE>;

这是一个任意大小的向量。现在我可以专门针对Vector2,Vector3Vector4:

template <typename T> class Vector<T, 2> : public _vec<T, 2>;

template <typename T>
using Vector2 = Vector<T, 2>;

我会让你知道这会变得多么可怕......;P

编辑2:它有效,但没有成功...... :(

标签: c++

解决方案


不,这是不可能的。

翻译阶段,预处理阶段在模板实例化阶段之前。因此,在这种情况下,您最终将没有定义的变量,template Vector因为SIZE在预处理阶段没有定义。

根据 C++ 标准,[cpp.cond]/9

在执行了由于宏扩展和定义宏表达式has-include-expressions 的true评估而导致的所有替换之后,除andfalse之外的所有剩余标识符和关键字都替换为pp-number 0,然后转换每个预处理标记成令牌。

所以SIZE这里的值将是0,因此条件包含的条件都不满足。

相反,您可以专门化您的模板,使其具有用于不同实例化的不同变量。


推荐阅读