Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> std::vector и оператор копирования, Для объектов с константными полями 
V
    Опции темы
SaDFromSpb
Дата 9.12.2006, 20:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 5.4.2006
Где: Санкт-Петербург

Репутация: 3
Всего: 3



Вот, сегодня обнаружил такой неприятный факт, что объекты с константными полями нельзя помещать в std::vector, потому что в его недрах используется оператор присваивания.
Вот и приходится решать мучительный вопрос, то ли не использовать константные поля, то ли вот так извращаться:
Код

struct Element {
   Element(int k) : key(k) {};
   void operator=(const Element& other) { int& rkey = const_cast<int&>(key); rkey = other.key; };
   const int key;
};

Обидно и непонятно. Этого, что, предусмотреть не могли? Обязательно operator=() в векторе надо было использовать? Я понимаю, что можно в исходники залезть и понять, что на самом деле все круто, и, раз умные дядки так сделали, то так и надо. Но времени туда залазить нету...

Это сообщение отредактировал(а) SaDFromSpb - 9.12.2006, 20:14


--------------------
"За исключением части, касающейся потоков, библиотека Loki написана на стандартном языке С++. Увы, это означает, что многие современные компиляторы не смогут работать с ней в полном объеме." (А. Александреску. Modern C++ design. 2001)
PM   Вверх
Daevaorn
Дата 9.12.2006, 20:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Цитата(SaDFromSpb @  9.12.2006,  21:03 Найти цитируемый пост)
Обязательно operator=() в векторе надо было использовать? 

а что ещё? Это семантика языка - никуда не деться.
PM MAIL WWW   Вверх
SaDFromSpb
Дата 9.12.2006, 20:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 5.4.2006
Где: Санкт-Петербург

Репутация: 3
Всего: 3



Daevaorn, Нет, я все-таки не понимаю. Оператор присваивания может пригодиться, когда старое содержимое вектора копируется в новое место при увеличении его объема. Но и в этом случае можно (а это будет и логичнее) обойтись конструктором копирования.
Хотя для этого они по-ходу все таки используют копирование:
Код

  template<typename _RandomAccessIter, typename _BidirectionalIter>
    inline _BidirectionalIter
    __copy_backward(_RandomAccessIter __first, _RandomAccessIter __last, 
            _BidirectionalIter __result,
            random_access_iterator_tag)
    {
      typename iterator_traits<_RandomAccessIter>::difference_type __n;
      for (__n = __last - __first; __n > 0; --__n)
        *--__result = *--__last;   // РУГАЕТСЯ ВОТ ЗДЕСЬ
      return __result;
    }

Отваливается при первом push_back'e (видимо при ресайзе)
Зачем они так поступают? (Кстати, это цитата из файла stl_algobase.h, то есть vector для переразмещения вызывает некий общий метод для контейнеров...)

А может в других реализациях STL делают по-другому? У меня STL от gcc 3.3.3.

Это сообщение отредактировал(а) SaDFromSpb - 9.12.2006, 20:39


--------------------
"За исключением части, касающейся потоков, библиотека Loki написана на стандартном языке С++. Увы, это означает, что многие современные компиляторы не смогут работать с ней в полном объеме." (А. Александреску. Modern C++ design. 2001)
PM   Вверх
Daevaorn
Дата 9.12.2006, 20:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Цитата(SaDFromSpb @  9.12.2006,  21:32 Найти цитируемый пост)
Зачем они так поступают? (Кстати, это цитата из файла stl_algobase.h, то есть vector для переразмещения вызывает некий общий метод для контейнеров...)

По стандарту теребования для объекта, чтобы он мог применяться в контейнерах: CopyConstructible и Assignable. Объеты содержащие const члены данных не являются Assignable.
Решение - храни в контейнере указатели в какой-нибудь оболочке(т.е. "умные указатели")
PM MAIL WWW   Вверх
SaDFromSpb
Дата 9.12.2006, 20:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 5.4.2006
Где: Санкт-Петербург

Репутация: 3
Всего: 3



Цитата(Daevaorn @  9.12.2006,  20:46 Найти цитируемый пост)
По стандарту теребования для объекта, чтобы он мог применяться в контейнерах: CopyConstructible и Assignable. Объеты содержащие const члены данных не являются Assignable.

Понятно, надо было читать главу о контейнерах в целом =)
Как в все-таки много в этом языке всяческих нюансов, я просто поражаюсь! Вот уже больше года работаю и все поражаюсь... Может я тупой? =)))

Это сообщение отредактировал(а) SaDFromSpb - 9.12.2006, 20:56


--------------------
"За исключением части, касающейся потоков, библиотека Loki написана на стандартном языке С++. Увы, это означает, что многие современные компиляторы не смогут работать с ней в полном объеме." (А. Александреску. Modern C++ design. 2001)
PM   Вверх
UnrealMan
Дата 9.12.2006, 21:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 722
Регистрация: 30.3.2006

Репутация: 27
Всего: 32



Цитата(Daevaorn @  9.12.2006,  20:46 Найти цитируемый пост)
Решение - храни в контейнере указатели в какой-нибудь оболочке(т.е. "умные указатели") 

Интересно, какой смысл запрещать копирующее присвоение для объектов, предназначенных для хранения в контейнере-последовательности? :-)
Вероятно, тут достаточно всего лишь по-людски обеспечить неизменность key:

Код
struct Element {
    Element(int k) : key(k) {};
    int Key() const { return key; }
private:
    int key;
};


Это сообщение отредактировал(а) UnrealMan - 9.12.2006, 21:41
PM MAIL   Вверх
SaDFromSpb
Дата 9.12.2006, 21:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 263
Регистрация: 5.4.2006
Где: Санкт-Петербург

Репутация: 3
Всего: 3



UnrealMan, Хм.. Ну можно и так конечно =) Просто там в коде очень много всего, и хотелось отдельные классы как можно компактнее описывать. К тому же операций с этой структурой будет очень-очень много. - Будет время теряться из-за доступа через метод (хотя... в методе можно константную ссылку возвращать, а не копировать int ...).
Принципиально проблем у меня с этим нет. Просто одна вещь удивила и все. Вообще я там с const_cast намудрил конечно =)) В таком случае уж точно лучше с помощью private делать...


--------------------
"За исключением части, касающейся потоков, библиотека Loki написана на стандартном языке С++. Увы, это означает, что многие современные компиляторы не смогут работать с ней в полном объеме." (А. Александреску. Modern C++ design. 2001)
PM   Вверх
zabivator
Дата 10.12.2006, 23:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 7.6.2006
Где: нск

Репутация: 1
Всего: 2



SaDFromSpb, может использовать mutable?
СТОП!!!! гоню!!!!

Это сообщение отредактировал(а) zabivator - 10.12.2006, 23:00
--------------------
#include <zabivator>int main( int, char * [] ){   while( Zabivator::жив() ) Zabivator::моск()++;   return 0;}
PM MAIL WWW ICQ   Вверх
Earnest
Дата 11.12.2006, 16:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Нет большого смысла делать данные-члены класса константными. С точки зрения скомпилированного кода - вообще никакой. С точки зрения защиты - сделай private, внутри класса уж как-нибудь проконтролируешь. Если речь идет о "совсем" константах - используй static или enum.
Кроме того, концепция copy-constructable подразумевает и адекватно-реализованный оператор присваивания.
Если не требовать (в контейнерах STL) оператор присваивания, то придется требовать конструктор по умолчанию (для реализации некоторых операций), что гораздо хуже...
Смирись и привыкай: объекты, которые хранятся в контейнерах должны иметь семантику значений (т.е. быть copy-constractable). И вообще, удобства, предоставляемые STL (а также boost), требуют некоторых самоограничений. В конечном итоге это только улучшает дизайн.


--------------------
...
PM   Вверх
zabivator
Дата 12.12.2006, 09:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 171
Регистрация: 7.6.2006
Где: нск

Репутация: 1
Всего: 2



Цитата(Earnest @ 11.12.2006,  16:39)
удобства, предоставляемые STL (а также boost), требуют некоторых самоограничений. В конечном итоге это только улучшает дизайн.

+1!!!
--------------------
#include <zabivator>int main( int, char * [] ){   while( Zabivator::жив() ) Zabivator::моск()++;   return 0;}
PM MAIL WWW ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0626 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.