具有启用/禁用的匿名结构

时间:2016-07-22 19:28:07

标签: c++ struct unions

我有以下矢量类(矢量在空间,而不是数组):

template<typename T0, size_t S, typename = typename std::enable_if<std::is_arithmetic<T0>::value && (S > 1 && S < 5)>::type>
struct Vec
{
    using value_type = T0;
    using vector_type = Vec<T0, S>;
    using array_type = std::array<T0, S>;
    using index_type = size_t;
    using size_type = size_t;

    enum { num_components = S };

    array_type v;
};

,这样我就可以制作一个含有2,3或4个元素的矢量类型:

    template<typename T0>
    using Vec2 = Vec<T0, 2>;

    template<typename T0>
    using Vec3 = Vec<T0, 3>;

    template<typename T0>
    using Vec4 = Vec<T0, 4>;

访问的形式为v [0],v [1]等(为简洁起见,我不包括[]运算符重载)。有时我更喜欢x,y等,但不想要额外的&#34;。&#34;从命名结合中的结构。所以使用非标准的功能&#34; Visual Studio 2013尝试使用匿名联合,仅在S(维度)为2,3或4时启用该值,如下所示:

    template<typename T0, size_t S, typename = typename std::enable_if<std::is_arithmetic<T0>::value && (S > 1 && S < 5)>::type>
    struct Vec
    {
        using value_type = T0;
        using vector_type = Vec<T0, S>;
        using array_type = std::array<T0, S>;
        using index_type = size_t;
        using size_type = size_t;

        enum { num_components = S };

        union
        {
            array_type v;

            template<typename = typename std::enable_if<S == 2>::type>
            struct
            {
                value_type x, y;
            };

            template<typename = typename std::enable_if<S == 3>::type>
            struct
            {
                value_type x, y, z;
            };

            template<typename = typename std::enable_if<S == 4>::type>
            struct
            {
                value_type x, y, z, w;
            };
        };
    };

不幸的是,这给了我以下错误:

**error C2332: 'struct' : missing tag name**

在某种程度上,我认为它是。有没有办法实现我在这里尝试的东西?我确定启用/禁用anoymous结构几乎肯定会给编译器一个migrane。如果我给结构命名,我可以像这样使用匿名联合。

1 个答案:

答案 0 :(得分:2)

为什么你认为std :: array和struct {T x,T y,... T}的内存布局是一样的?只有使用#pragma pack将对齐设置重置为1时,才能访问它。对于其他人来说,对齐是不可预测的。

你想拥有

这样的课程
  1. 通过数据成员选择器提供访问权限,例如.x,.y等
  2. 通过operator []
  3. 提供对数据成员的直接访问
  4. 不会破坏默认数据成员对齐(std :: array是线性的,它会破坏类数据成员的编译器优化对齐)
  5. 以下代码符合上述要求,没有任何非标准功能:

    Caused by: java.lang.NullPointerException
    at com.google.protobuf.UnmodifiableLazyStringList.size(UnmodifiableLazyStringList.java:61)
    at java.util.AbstractList.add(AbstractList.java:108)
    at com.esotericsoftware.kryo.serializers.CollectionSerializer.read(CollectionSerializer.java:134)
    at com.esotericsoftware.kryo.serializers.CollectionSerializer.read(CollectionSerializer.java:40)
    at com.esotericsoftware.kryo.Kryo.readObject(Kryo.java:708)
    at com.esotericsoftware.kryo.serializers.ObjectField.read(ObjectField.java:125)
    ... 40 more