Название: Массив std::set Отправлено: Igors от Сентябрь 13, 2012, 15:32 Добрый день
Нужен массив std::set (ну или порожденных классов, указателей) каждый из которых хранит указатели на один и тот же класс, но использует свой функтор. Пример Код Так нет проблем но приходится перебирать theSetxx. А хотелось бы так Код
Спасибо Название: Re: Массив std::set Отправлено: Igors от Сентябрь 14, 2012, 00:09 Код: set<int> s = *(set<int> *)array[i]; Код Но так и компилиться не должно если set <int> нигде не объявлен и значит не "инстанциирован". А если объявить и как-то заткнуть рот компилятору, то все равно неясно как же он найдет нужный функтор, ведь метод find не виртуальный. Название: Re: Массив std::set Отправлено: VPS от Сентябрь 14, 2012, 07:39 Код Но так и компилиться не должно если set <int> нигде не объявлен и значит не "инстанциирован". А если объявить и как-то заткнуть рот компилятору, то все равно неясно как же он найдет нужный функтор, ведь метод find не виртуальный. Компилятор не ругается ???, но и пример мой на самом деле не корректен... Так как в нем постоянно определяется указатель на множество вида: set<int, less<int> >. Поэтому то и поиск во втором контейнере и не проходит... Название: Re: Массив std::set Отправлено: V1KT0P от Сентябрь 14, 2012, 08:10 Нужен массив std::set (ну или порожденных классов, указателей) каждый из которых хранит указатели на один и тот же класс, но использует свой функтор. Правильно ли я тебя понял: у тебя три отдельных массива из-за того что используются три разных своих функтора, а ты хочешь эти три отдельных массива запихнуть в один массив?Тогда почему ты не можешь сделать базовый функтор, от которого будут наследоваться остальные функторы. А в массиве будешь хранить только указатель на базовый. Даже если ты используешь не свои функторы и нет возможности их менять, то можно написать свой функтор обертку. В эту обертку заворачивать функторы. При чем если сделать на шаблонах, то вообще любой функтор можно будет завернуть. Название: Re: Массив std::set Отправлено: Igors от Сентябрь 14, 2012, 12:54 Правильно ли я тебя понял: у тебя три отдельных массива из-за того что используются три разных своих функтора, а ты хочешь эти три отдельных массива запихнуть в один массив? У меня не 3 отдельных массива, а 3 (реально больше) std::set. Все они работают с типом MyClass * (первый template аргумент) но отличаются функторами (второй template аргумент), т.е. все они имеют разный тип. Тогда почему ты не можешь сделать базовый функтор, от которого будут наследоваться остальные функторы. А в массиве будешь хранить только указатель на базовый. А как я могу "хранить функтор"? Прошу исполнитьНазвание: Re: Массив std::set Отправлено: V1KT0P от Сентябрь 14, 2012, 21:00 У меня не 3 отдельных массива, а 3 (реально больше) std::set. Все они работают с типом MyClass * (первый template аргумент) но отличаются функторами (второй template аргумент), т.е. все они имеют разный тип. А как я могу "хранить функтор"? Прошу исполнить Вот сразу два варианта:1) Путем наследования от интерфейса, это если можно править классы функторов. 2) Путем шаблонного наследования от интерфеса, это если нельзя править классы функторов. Код
Название: Re: Массив std::set Отправлено: Igors от Сентябрь 14, 2012, 21:32 Вот сразу два варианта: Все функторы в моих руках и, как обычно, они очень просты. Приведенный Вами код понятен - да, можно сделать функторам общую базу, а можно и обернуть. Указатели на созданные экземпляры классов поместить в контейнер - нема квешнзов. Ну а std::set то где? Напомню что он определяется как1) Путем наследования от интерфейса, это если можно править классы функторов. 2) Путем шаблонного наследования от интерфеса, это если нельзя править классы функторов. Код Где MyFunctor - тип (а не экземпляр) Название: Re: Массив std::set Отправлено: V1KT0P от Сентябрь 14, 2012, 22:07 Код: [quote author=Igors link=topic=23034.msg162748#msg162748 date=1347647552] [/quote] Не использовал set, теперь понял что не про то подумал. Пока что в голову пришло только сделать для set-а шаблонный интерфейс, в который вынести нужные функции которые наследуемые классы переопределят и который будет знать только о типе хранимого объекта. А уже наследованные будут знать класс который сравнивает. Тогда просто объявишь три set-а, приведешь их к интерфейсу и запихнешь в один массив. Название: Re: Массив std::set Отправлено: VPS от Сентябрь 14, 2012, 23:27 Нашёл интересную статью "Неявное приведение между родственными шаблонами С++" (http://elwood.su/?p=181)
И на базе её попробовал сделать пример (http://www.prog.org.ru/index.php?action=dlattach;topic=23034.0;attach=5336), правда поиск производится методом algorithm::find и слишком много приведений к базовому типу... Но видимо без этого не обойтись, так как в общем контейнере надо хранить объекты разных типов, преобразованных к базовому. П.С.: если использовать метод find шаблонного класса set, то ничего не находит... Название: Re: Массив std::set Отправлено: VPS от Сентябрь 17, 2012, 21:31 Немного изменил предыдущий пример. Теперь поиск set::find() работает.
Исходник, здесь (http://www.prog.org.ru/index.php?action=dlattach;topic=23034.0;attach=5340). Название: Re: Массив std::set Отправлено: V1KT0P от Сентябрь 17, 2012, 22:01 Немного изменил предыдущий пример. Теперь поиск set::find() работает. А теперь добавь в класс Less или Greater вот такую банальную строчку:Исходник, здесь (http://www.prog.org.ru/index.php?action=dlattach;topic=23034.0;attach=5340). Код И получи чудеса. Название: Re: Массив std::set Отправлено: VPS от Сентябрь 18, 2012, 07:22 Немного изменил предыдущий пример. Теперь поиск set::find() работает. А теперь добавь в класс Less или Greater вот такую банальную строчку:Исходник, здесь (http://www.prog.org.ru/index.php?action=dlattach;topic=23034.0;attach=5340). Код И получи чудеса. Получил... ??? Направьте меня на тему, что про это почитать (если правильно понял, то что-то не так с преобразованием к нужному типу). Название: Re: Массив std::set Отправлено: V1KT0P от Сентябрь 18, 2012, 08:42 Получил... ??? Чего там читать, добавили одну переменную и адреса всех остальных сдвинулись. Добавим новую функцию и адреса остальных функций сдвинутся. В результате сперва адреса функций и переменных совпадали и можно было C style cast-ом(Именно это ты и делал, только замаскировал статик кастом а так получил тот-же C style cast) безнаказанно. В реальном же приложении если делают новый класс, то он чем-то отличается. Вот и получается что чуть сдвинулись переменные и все начало неправильно работать. Поэтому в C++ специально сделали безопасный статик_каст, а за C style cast надо по рукам бить. Сколько я уже наслышался проблем из-за него.Направьте меня на тему, что про это почитать (если правильно понял, то что-то не так с преобразованием к нужному типу). Название: Re: Массив std::set Отправлено: VPS от Сентябрь 18, 2012, 08:49 Чего там читать, добавили одну переменную и адреса всех остальных сдвинулись. Добавим новую функцию и адреса остальных функций сдвинутся. В результате сперва адреса функций и переменных совпадали и можно было C style cast-ом(Именно это ты и делал, только замаскировал статик кастом а так получил тот-же C style cast) безнаказанно. В реальном же приложении если делают новый класс, то он чем-то отличается. Вот и получается что чуть сдвинулись переменные и все начало неправильно работать. Поэтому в C++ специально сделали безопасный статик_каст, а за C style cast надо по рукам бить. Сколько я уже наслышался проблем из-за него. Спасибо за разъяснение!Название: Re: Массив std::set Отправлено: Igors от Сентябрь 18, 2012, 12:36 Чего там читать, добавили одну переменную и адреса всех остальных сдвинулись. Добавим новую функцию и адреса остальных функций сдвинутся. Думаю что можно добавить сколько угодно ф-ций (виртуальных или нет) и ничего не сдвинется. А вариант вполне рабочий, спасибо, VPS . На мой взгляд маскировать приведение ни к чему, проще сделать один static_cast на вставке в вектор. И провериться в конструкторе функтора, напрКод Пробовал разобраться почему "сдвигается" Код: struct _Rb_tree_impl : public _Node_allocator Ну в принципе обеспечить функторы одного размера - не проблема. Название: Re: Массив std::set Отправлено: DmitryM от Сентябрь 18, 2012, 16:22 Вот сразу два варианта: Все функторы в моих руках и, как обычно, они очень просты. Приведенный Вами код понятен - да, можно сделать функторам общую базу, а можно и обернуть. Указатели на созданные экземпляры классов поместить в контейнер - нема квешнзов. Ну а std::set то где? Напомню что он определяется как1) Путем наследования от интерфейса, это если можно править классы функторов. 2) Путем шаблонного наследования от интерфеса, это если нельзя править классы функторов. Код Где MyFunctor - тип (а не экземпляр) Код Идея понятна? Название: Re: Массив std::set Отправлено: Igors от Сентябрь 18, 2012, 17:32 Во блин, тут же все просто, чего я ломился в открытую дверь? :) Есть же возможность передать функтор в конструторе
Код Ну ничего, подучил матчасть :) |