可能不是最明智的选择,但是为 Vertex<T, N>
建模抽象类 Vertex2<T>
, Vertex3<T>
和 Vertex4<T>
实现,提供基本访问。它的结构如下:
template<typename T, unsigned N>
class _Vertex {
const unsigned _size = N;
T _data[N];
public:
inline _Vertex() : _data() {};
inline T const& operator[](int pos) const { return _data[pos]; }
inline T & operator[](int pos) { return _data[pos]; }
};
说我想实现Vertex2<T>
作为Vertex<T, 2>
, 并提供像 x
这样的别名和 y
.最合适的方法是添加如下函数:
inline T const& x() const { return (*this)[0]; }
inline T & x() { return (*this)[0]; }
这将针对我要添加的每个属性或别名重复进行。这不是一个糟糕的设计,但使用起来很棘手,因为 v
类型为 Vector2<float>
, v.x() = 1.0f
不如v.x = 1.0f
友好.
有没有办法提供更清晰、更友好的别名?
我的主要想法是“滥用”内存布局,提供对 _data[i]
的访问因此,但我不知道从哪里开始。
这个问题是基于我对 vertex.h
的“重新想象”为作业提供的头文件,因此这与作业有关,但我可以向您保证,结尾不是。这只是我的好奇心让我没有做作业!
最佳答案
我穿上长袍,戴上牦牛帽。
operator->*
在 C++ 中显然没有得到充分利用。我们可以重载以一种类似于成员访问的方式来获取我们选择的标签类型。这是一个简化的示例:
template <size_t I> struct index_t { };
constexpr index_t<0> x{};
constexpr index_t<1> y{};
struct Vector {
int data[2];
template <size_t I>
int& operator->*(index_t<I> ) { return data[I]; }
int& operator[](size_t idx) { return data[idx]; }
};
有了它,我们可以:
int main()
{
Vector v{1, 2};
std::cout << v.data[0] << ' ' << v.data[1] << '\n'; // 1 2
v->*x = 42;
v->*y = 17;
std::cout << v.data[0] << ' ' << v.data[1] << '\n'; // 42 17
}
就是说,不要这样做。 C++ 没有属性。正确的做法是将返回左值引用的函数命名为:
int& x();
int& y();
它可能不像 v.x
那样“好”,但它可以完成工作而无需向您的类添加额外的成员。
关于c++ - 在 C++ 中为父类数据数组提供别名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46592420/