将联合变量公开为类成员变量

时间:2018-11-19 17:38:28

标签: c++ templates union

我已经成功编译了以下代码:

Vector

它可以按预期工作,但是我希望结构Vector<int, 3> vec; vec.x ...; vec.components[0] ...;将数据的变量作为其自己的成员变量公开。

有可能吗?

该解决方案将允许我执行Data

联合的目的是轻松地将向量的组成部分作为数组或单个访问。

此外,如果您碰巧知道实现模板联合T x专业化的更好方法,请说一下,因为我发现它有点硬编码。最好递归地添加变量,而不必添加以前的专业化变量。

例如,我只需要声明一次class User < ApplicationRecord DEFAULT_SETTINGS = { color: 'blue', homepage: 'rubyonrails.org' } store :settings, accessors: DEFAULT_SETTINGS.keys DEFAULT_SETTINGS.each do |key,value| define_method(key) { settings[key] or value } end end

1 个答案:

答案 0 :(得分:5)

我认为您需要使设计和代码更加清晰。

使用

template <>
union Data<3>
{
    T x;
    T y;
    T z;
    std::array<T, 3> components;
};

听起来不对。您需要拥有{x, y, z}components,而不是xyzcomponents。您需要的是类似

的东西
template <>
union Data<3>
{
    struct
    {
       T x;
       T y;
       T z;
    } members;
    std::array<T, 3> components;
};

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

    std::array<T, N> components;

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

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

如果您需要通过componentsx和类似y的抽象公开z的元素,最好添加成员函数。

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];
   }
};

使用上面的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;
}

如果您使用

   Vector<int, 2> v2;
   v2.z() = 20;

您应该会遇到编译时错误。

您可以添加上述函数的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];
   }
};