玩具示例:
template<typename T, std::size_t N>
class static_vector
{
public:
T& operator[](std::size_t i) { return m_elements[i]; }
T const& operator[](std::size_t i) const { return m_elements[i]; }
private:
std::array<T, N> m_elements;
};
template<typename T>
class vector3
: public static_vector<T, 3>
{
public:
using vector_type = static_vector<T, 3>;
// x = vector_type::operator[](0);
// y = vector_type::operator[](1);
// z = vector_type::operator[](2);
};
让vector3<float> pos;
。我想通过pos[0]
访问pos.x
。显然,如果pos
被声明为const
,我希望pos.x
是只读的。
这可能吗?
让我强调一点,我不想使用表格
的访问者功能T& x() { return (*this)[0]; }
T const& x() const { return (*this)[0]; }
答案 0 :(得分:1)
使用您想要的确切语法,没有零成本方法。
放宽成本(编译,维护,内存使用和运行时)或语法(你的()
就是一个例子)可以得到你想要的东西。
答案 1 :(得分:0)
我在您的问题中添加了评论,但我想我会添加一些代码以澄清答案。请注意,以下内容不是一个好主意。
您可以使用简单的指针算法来解释struct
的成员,就好像它们是array
中的元素一样。由于struct
成员的类型和伪array
中的元素类型相同,我们可以安全地将其重新解释为另一个并提出警告 struct
成员之间没有填充。
C ++标准没有提供在struct
中定义填充的方法,因此您必须依赖编译器特定的指令。但我相信MSVC和GCC都支持#pragma pack
。
#pragma pack(push, 1)
template <typename T>
struct Vec3
{
T x;
T y;
T z;
T& operator[](size_t i) { return *(&x + i); }
const T& operator[](size_t i) const { return *(&x + i); }
};
#pragma pack(pop)
那为什么这不是一个好的解决方案呢?
您依赖于编译器特定的指令,使您的代码不那么便携。
您需要明确声明每个成员,这意味着您需要Vec2,Vec3和Vec4的单独模板。
所有架构都不支持1字节对齐,这使得代码的可移植性降低。
即使在支持未对齐内存访问的架构(例如x86)上,它也会带来性能损失。