Const вектор не-const объектов

при определении функции в интерфейсе:

virtual void ModifyPreComputedCoeffs ( std::vector < IndexCoeffPair_t > & model_ ) = 0;

мы хотим указать, что вектор model_ не должен быть изменен в том смысле, что операции push_back etc не должны выполняться на векторе, но объекты структуры IndexCoeffPair_t в model_ могут быть изменены. Как нам это уточнить ?

virtual void ModifyPreComputedCoeffs ( const std::vector < IndexCoeffPair_t > & model_ ) = 0;

не работает, я думаю.

5 ответов


концепция c++ const-корректности ИМО переоценена. То, что вы только что обнаружили, является одним из больших ограничений: оно не масштабируется по составу. Чтобы создать const-вектор неконст-объектов, вам необходимо реализовать свой собственный тип вектора. Обратите внимание, что, например, даже стандартная библиотека должна была ввести новые типы для const_iterators.

мое предложение-использовать const-корректность там, где вы вынуждены, а не везде, где можете. Теоретически const корректность должен помогать программистам, но стоит очень дорого из-за синтаксиса и очень примитивен (всего один бит, не масштабируется по составу, даже требует дублирования кода).

также по моему опыту, эта предполагаемая большая помощь на самом деле не такая большая... большинство ошибок, которые он ловит, связаны с самим механизмом const-correctness, а не с программной логикой.

когда-либо задавались вопросом, почему большинство языков (включая те, которые разработаны после C++) не реализовали эту идею?


вместо того, чтобы передавать вектор в функцию, сделайте то, что делает стандартная библиотека, и передайте пару итераторов.

virtual void ModifyPreComputedCoeffs ( std::vector < IndexCoeffPair_t >::iterator & model_begin, std::vector < IndexCoeffPair_t >::iterator & model_end )

Это, вероятно, будет в C++14 как std:: dynarray.

на самом деле, если размер фиксируется во время компиляции, вы можете использовать std:: array. Но это, вероятно, больше используется для таких вещей, как встроенное Программирование, буферы, матрицы и так далее, как часто вы не знаете желаемый размер до выполнения или вы хотите, чтобы он был настроен.


Если вы можете изменить IndexCoeffPair_t, вы можете добавить некоторые функции-члены const и использовать их для изменения некоторых из своих членов, сделав члены изменяемыми с помощью ключевого слова mutable. Это своего рода Хак, хотя, так как теперь вы сможете изменить содержимое любого const IndexCoeffPair_t.

пример:

class IndexCoeffPair_t {
public:
    void changeX(int newVal) const {
        x = newVal;
    }

private:
    mutable int x;
};

вы можете попробовать создать const std::vector<YouType*>. Тогда вы не можете изменить вектор, но вы можете изменить объекты внутри вектора. Но будьте точны, потому что вы будете изменять исходные объекты, а не копии.

использование интеллектуальных указателей или необработанных указателей зависит от ваших вариантов использования: у вас есть вектор или просто вектор наблюдателей.