我想实现一个自定义向量类myVector<dataT>,它与std::vector完全相同,它的索引从作为参数给定的偏移量开始。
示例用法如下:
myVector<int> vec(3,0,1); // length=3, initial_value=0, offset=1
assert(vec.size()==3);
vec[1]=1, vec[2]=2, vec[3]=3;
assert(vec[1]==1);
assert(vec[3]==3);基本上,我希望覆盖dataT& operator[]方法,而所有其他方法都保持不变。但是我需要处理offset是变量而不是常量的情况。
如果offset是常量,我可以将它声明为模板参数。但通过这种方式,我不能将变量传递为offset。
template <typename dataT, size_t offset>
class myVector{
//definition
};
myVector<int, 1> vec; //valid
int offset=1;
myVector<int, offset> vec; //invalid我有几种可能的方法来实现myVector,每个方法都需要一些锅炉板代码:
方法1:继承std::vector,接受offset作为构造函数的参数
template <typename dataT>
class myVector : public std::vector {
myVector(int n, int v0, int offset) {}
dataT& operator [] (int index) {return this->at(index-offset);}
}通过继承,像size, push_back这样的方法会自动工作。但是要接受offset作为构造函数的参数,我必须对所有重载的构造函数进行更改,这可以是冗长的。
方法2:继承std::vector,使offset成为数据成员。
类似于方法1,但我们不将offset作为构造函数参数传递。相反,我们使用setOffset()为其赋值。
虽然这个方法消除了大多数样板代码,但是每个myVector定义都需要一个setOffset,这也不是很优雅。
方法3:std::vector作为myVector的数据成员。
template <typename dataT>
class myVector {
std::vector<dataT> stdVector;
myVector(const std::vector<dataT> _stdVector, int offset) {}
}这样,myVector的定义/初始化就变得简单了,但是我们需要编写myVector::size(), myVector::push_back(),这也是冗长的。
因此,我对上面提到的所有三种方法都很关心。是否有任何优雅的实现,既使初始化简单,又不涉及样板代码?谢谢!
发布于 2022-04-01 01:24:58
方法4:将的第一个参数偏移到构造函数,使用变量参数作为其余参数,并完善地转发它们。
template<typename ...Args>
myVector(int offset, Args && ...args) : std::vector{std::forward<Args>(args)...}
{
}这解决了单个实现覆盖所有std::vector构造函数的直接问题。
现在,子类std::vector和所有其他C++库容器都存在其他问题,这些问题以前已经被讨论过了。这可能与您无关,您应该仔细考虑它的含义(通常的对象是缺少虚拟析构函数)。但是,这不属于最初问题的范围.
https://stackoverflow.com/questions/71700710
复制相似问题