我正在派生stl容器类向量并尝试重载[]运算符以提供有关使用下标访问元素的范围检查。
但是当我尝试创建派生类Vec
的const对象时,我遇到了编译错误。
例如,下面是代码:
template<class T>
class Vec : public vector<T>
{
public:
Vec(): vector<T>()
{
}
Vec(int i):vector<T>(i)
{
}
T& operator[](int i)
{
return at(i);
}
const T& operator[](int i) const
{
if(i>=size())
cout<<"error"<<endl;
return at(i);
}
};
void main()
{
Vec<int> v1(10); //works fine
const Vec<int> v(10); //error
}
为什么是代码 const vector v(10);工作,但 const Vec v1(10);不起作用。 有什么我想念的吗?为什么我无法创建const对象?
答案 0 :(得分:0)
像std::vector
这样的STL类通常不是派生自。
但代码正常运行如下:
template<class T>
class Vec : public vector<T>
{
public:
Vec(): vector<T>()
{
}
Vec(int i):vector<T>(i)
{
}
T& operator[](int i)
{
return vector<T>::at(i);
}
const T& operator[](int i) const
{
if(i>=vector<T>::size())
cout<<"error"<<endl;
return vector<T>::at(i);
}
};
int main()
{
Vec<int> v1(10); //works fine
const Vec<int> v(10); //error
v1.push_back(5);
v1.push_back(6);
int i = v1[3];
}
需要使用at
或size
调用基础std::vector
中的函数vector<T>::at(i)
和this->at(i)
。
当基类是模板时,这总是正确的:然后&#34; vector<T>
&#34;是一个依赖名称(其含义取决于模板参数T
),在这种情况下,其成员不会自动导出到Vec
类定义的范围。
同样cout<"error"
必须为cout<<"error"
,main
必须返回int
。
const
不会造成问题。
一般情况下,push_back
无法使用const std::vector
,因为它会修改向量。但是复制初始化或列表初始化可用于创建非空const std::vector
。例如
const std::vector<int> vec {1, 2, 3};
答案 1 :(得分:0)
Bjarne Stroustrup在&#34; C ++之旅&#34;中介绍了这个问题。
template<typename T>
class Vec : public std::vector<T> {
public:
using vector<T>::vector; // use the constructors from vector (under the name Vec)
T& operator[](int i)
{ return vector<T>::at(i); }
const T& operator[](int i) const
{ return vector<T>::at(i); }
}
&#34; Vec继承了vector中的所有内容,除了它重新定义的下标操作以进行范围检查。&#34;