Const_cast для вектора с объектом

Я понимаю, что const_cast для удаления постоянства объектов - это плохо,

У меня есть следующий вариант использования,

//note I cannot remove constness in the foo function
foo(const std::vector<Object> & objectVec) {

   ...
   int size = (int) objectVec.size();
   std::vector<Object> tempObjectVec;
   //Indexing here is to just show a part of the vector being
   //modified
   for (int i=0; i < (int) size-5; ++i) {
       Object &a = const_cast<Object&> objectVec[i];
       tempObjectVec.push_back(a);
   } 
   foo1(tempObjectVec);
}  

Если я изменю объекты tempObjectVec в foo1, изменятся ли исходные объекты в ObjectVec, я говорю «да», поскольку я передаю ссылки, это еще более эффективно. Можете предложить альтернативы.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
1 474
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Ну, это зависит от Object. Но объекты находятся копируются, когда вы передаете их в push_back. Вы можете проверить это, добавив отладочный код в конструктор копирования. Так что, если Object ведет себя хорошо и хранит отдельные копии отдельно, тогда foo1 может изменить вектор, который ему достанется.

Более эффективный способ сделать это - заставить foo1 принимать начальный и конечный итераторы:

void foo1(std::vector<Object>::const_iterator start,
          std::vector<Object>::const_iterator end);

...
foo1(objectVec.begin(), objectVec.end() - 5);

Если вы не используете const_cast, система типов гарантирует, что foo1 не изменит никаких элементов, поскольку это const_iterators.

Ваш tempObjectVec не может быть вектором ссылок, поэтому я предполагаю, что он должен быть объявлен примерно так:

std::vector<Object> tempObjectVec;

Когда вы запускаете tempObjectVec.push_back(a), будет сделана копия объекта, чтобы вставить его в вектор tempObjectVec. Поскольку это создание копии, вам даже не нужно использовать const_cast для удаления констант, я не понимаю, зачем вам это нужно.

Я считаю, что это то утверждение, которое вы ищете:

const_cast<std::vector<Object>&> (objectVec), это вернет ссылку на неконстантный std::vector, который должен быть приемлем для foo1 (я предполагаю).

Изменение исходного примера:

foo(const std::vector<Object> & objectVec) {

    ...
    foo1(const_cast<std::vector<Object> &>(objectVec));
}

Однако я рекомендую посмотреть на фактические требования foo1, которые требуют, чтобы он использовал неконстантный вектор, поскольку вы, кажется, указываете, что все, что вас интересует, - это изменение самих экземпляров Object.

Как уже говорят другие, ваш вектор push_back берет ссылку, но затем копирует объект, на который ссылается. Итак, в конце вы получаете копию objectVec[i] в вашем tempObjectVec.

Вектор не может хранить ссылки, потому что они не могут быть назначены (присвоение ему влияет не на саму ссылку, а на объект, на который вместо этого ссылается), что является требованием для объектов, которые должны храниться в векторе. Ссылки тоже не являются объектами. У них нет своего размера. Поэтому они не могут быть помещены в массив или любой вектор. Обычно вы хотите хранить указатели или интеллектуальные указатели в таком контейнере, чтобы ссылаться на какой-либо другой объект. Загляните в библиотеку boost pointer container, которая выглядит именно так, как вам нужно.

Другие вопросы по теме