我已经得到了刚刚成功编译的代码:
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;
};
它按预期工作,但是我希望结构
Vector
将数据的变量公开为其自己的成员变量。
可以吗?
解决方案将允许我做
Vector<int, 3> vec; vec.x ...; vec.components[0] ...;
联合的目的是轻松地以数组和单独方式访问向量的组件。
另外,如果您碰巧知道更好的方法来实现模板化联合
Data
专业化,请说出来,因为我发现它有点硬编码。如果能够递归地添加变量,而无需添加之前特化的变量,那就太完美了。
例如,我只需要声明一次
T x
。
我认为你需要让你的设计和代码更加清晰。
使用
template <>
union Data<3>
{
T x;
T y;
T z;
std::array<T, 3> components;
};
听起来不对。您需要有
{x, y, z}
或 components
,而不是 x
、或 y
、或 z
、或 components
。你需要的是类似的东西
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;
};
如果需要通过
components
、x
和 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];
}
};