将union的变量公开为类成员变量

The*_*ver -2 c++ union templates

我已经成功编译了这段代码:

template <typename T, unsigned int N>
struct Vector
{
    struct Vec1
    {
        T x;
    };

    struct Vec2 : public Vec1
    {
        T y;
    };

    struct Vec3 : public Vec2
    {
        T z;
    };

    struct Vec4 : public Vec3
    {
        T w;
    };

    template <unsigned int N>
    union Data
    {
        std::array<T, N> components;
    };

    template <>
    union Data<1>
    {
        Vec1 vec;
        std::array<T, 1> components;
    };

    template <>
    union Data<2>
    {
        Vec2 vec;
        std::array<T, 2> components;
    };

    template <>
    union Data<3>
    {
        Vec3 vec;
        std::array<T, 3> components;
    };

    template <>
    union Data<4>
    {
        Vec4 vec;
        std::array<T, 4> components;
    };

    Data<N> data;
};
Run Code Online (Sandbox Code Playgroud)

它按预期工作,但是我希望struct Vector将数据的变量公开为它自己的成员变量.

可能吗?

解决方案可以让我这样做 Vector<int, 3> vec; vec.x ...; vec.components[0] ...;

联合的目的是将矢量的组件轻松地作为数组和单独访问.

此外,如果你碰巧知道一个更好的方法来实现模板化联合Data专业化,请说明,因为我发现它有点硬编码.递归添加变量而不必添加先前特化的变量将是完美的.

例如,我只需要声明T x一次.

R S*_*ahu 5

我认为你需要为你的设计和代码带来一些清晰度.

用于

template <>
union Data<3>
{
    T x;
    T y;
    T z;
    std::array<T, 3> components;
};
Run Code Online (Sandbox Code Playgroud)

听起来不对劲.你需要{x, y, z}componentsx,或y,或z,或components.你需要的是一些东西

template <>
union Data<3>
{
    struct
    {
       T x;
       T y;
       T z;
    } members;
    std::array<T, 3> components;
};
Run Code Online (Sandbox Code Playgroud)

话虽如此,最干净的成员变量就是

    std::array<T, N> components;
Run Code Online (Sandbox Code Playgroud)

就成员变量而言,Vector可以定义为:

template <typename T, unsigned int N>
struct Vector
{
   std::array<T, N> components;
};
Run Code Online (Sandbox Code Playgroud)

如果需要公开componentsthrough x,yz类似抽象的元素,最好添加成员函数.

template <typename T, unsigned int N>
struct Vector
{
   std::array<T, N> components;

   T& x()
   {
      static_assert(N > 0);
      return components[0];
   }

   T& y()
   {
      static_assert(N > 1);
      return components[1];
   }

   T& z()
   {
      static_assert(N > 2);
      return components[2];
   }
};
Run Code Online (Sandbox Code Playgroud)

有了上面的定义Vector,下面的main函数应该可以工作.

int main()
{
   Vector<int, 1> v1;
   v1.x() = 20;

   Vector<int, 2> v2;
   v2.x() = 20;
   v2.y() = 30;

   Vector<int, 3> v3;
   v3.x() = 20;
   v3.y() = 30;
   v3.z() = 40;
}
Run Code Online (Sandbox Code Playgroud)

如果你使用

   Vector<int, 2> v2;
   v2.z() = 20;
Run Code Online (Sandbox Code Playgroud)

你应该得到一个编译时错误.

您可以添加const上述函数的版本,以使成员函数也可以使用const对象.

template <typename T, unsigned int N>
struct Vector
{
   std::array<T, N> components;

   T& x()
   {
      static_assert(N > 0);
      return components[0];
   }

   T const& x() const
   {
      static_assert(N > 0);
      return components[0];
   }

   T& y()
   {
      static_assert(N > 1);
      return components[1];
   }

   T const& y() const
   {
      static_assert(N > 1);
      return components[1];
   }

   T& z()
   {
      static_assert(N > 2);
      return components[2];
   }

   T const& z() const
   {
      static_assert(N > 2);
      return components[2];
   }
};
Run Code Online (Sandbox Code Playgroud)