Я пишу класс CustomVector, внутренне сохраняя данные с помощью стандартного вектора:
template <class T>
class CustomVector {
friend class CustomVector_ref<T>;
public:
...
private:
std::vector<T> _data;
};
Затем для извлечения подвекторов из CustomVector я использую указатели хранения классов для каждого элемента данных:
template <class T>
class CustomVector_ref {
public:
//Returns the value stored in CustomVector
//and pointed-to by _data_ref
T& operator[] (size_t id) { return *_data_ref[id] }
const T& operator[] const (size_t id) { return *_data_ref[id] }
...
private:
std::vector<T*> _data_ref;
};
Теперь, чтобы проиллюстрировать мою проблему, достаточно рассмотреть простое построение структуры затрат, ссылаясь на все элементы CustomVector
template<class T>
CustomVector_ref<T>::CustomVector_ref(CustomVector<T>& cv)
{
for (T& el : cv._data)
_data_ref.push_back(&el);
}
Это работает отлично, но если у меня есть const CustomVector, мне нужно также определить конструктор:
template<class T>
CustomVector_ref<T>::CustomVector_ref(const CustomVector<T>& cv)
{
for (const T& el : cv._data)
_data_ref.push_back(const_cast<T*>(&el));
}
Это тоже работает, но если объект CustomVector_ref не объявлен как const, то с помощью неконстантного оператора [] можно записать данные в объект const CustomVector.
const CustomVector<int> cv(...) //CostumVector is somehow constructed,
//that does not matter now
std::cout<<cv[0]<<std::endl; //output 1 for example
CustomVector_ref<int> cvr(cv)
cvr[0] = 2;
std::cout<<cv[0]<<std::endl; //now cv[0] stores 2
Можно ли избежать этого поведения?
Я заметил, что это происходит также со стандартными векторами, например
const std::vector<int> v(1,1);
std::vector<int*> vp;
vp.push_back(const_cast<int*>(&v[0]));
*vp[0] = 2;
std::cout<<v[0]<<std::endl; // now v[0] stores 2, not 1
Итак, поскольку это стандартный С++, я не слишком беспокоюсь, чтобы исправить свой CustomVector, но было бы неплохо узнать, есть ли (не слишком запутанное) решение.