派生类中的成员字段别名(无访问器函数)

时间:2018-03-28 16:31:30

标签: c++ c++17

玩具示例:

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

2 个答案:

答案 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)上,它也会带来性能损失。