[Это перепост темы, по просьбам трудящихся, из форума исходники. За два дня на нее не было ни одного ответа, которых так хотелось. В следствии чего была высказана мысль написать еще раз в форум c++.
Я и несколько товарищей надеемся узнать мнение РСДН по данному коду.
Основной аргумент против этого кода: он не нужен, есть boost::tuple.
Я отбиваюсь тем, что мой код проще и ближе к реализации Tuple, как это сделано в D. И не требует написания лишнего кода.
Два основных вопроса: нужен ли данный код и можно ли его использовать в реальных задачах?
]
Дата: 02.04.11 13:34
Вчера совершенно случайно начали обсуждать tuple и их реализацию в С++, может они шутили, но я занялся и вот что получилось.
Простенько и со вкусом. Без кучи шаблонов. Так как я видел это в D.
Создать Typle не проблема, сложнее оказалось сделать их использование достаточно простым.
В итоге получилось сделать даже проще, чем я мог предполагать. Хватило одного класса.
В принципе, переменные в списке можно разделять любым знаком TPL a , b + c — d * e / f < g > h; но думаю лучше оставить одну запятую, хотя практика показывает, что этого мало.
Единственный минус, это переменные после вызова функции: T(), a, b... К сожалению перед функцией так и не получилось сделать. при использовании +-*/<> переменные выполняли эти операции раньше. При разделении запятыми переменные вообще исчезали. В общем, против направления выполнения не попрешь.
Контроль за количеством переменных и типами оставляю на программиста, если он ошибется вызывается memcpy(0, 0, 1); мне показалось это достаточно прямолинейное сообщение об ошибке. Можно сделать что-нибудь попроще.
Таким же способом можно передавать туплы в функции. Запятые не прошли, пришлось использовать знаки +.
Хотелось бы узнать, есть ли еще реализации туплов. Про туплы на boost слышал. Мне не понравилось. Там каждый шаг нужно описывать.
Хотелось бы узнать, есть ли желающие использовать мою разработку. Я не знаю, буду ли использовать ее, или более привычное получение результатов через адреса int &i. Я обычно стремлюсь к оптимизации, int &i быстрее. Хотя тут действительно небольшие потери в скорости.
Разработка еще не закончена. Есть еще пара идей по ускорению. Если будут пожелание по расширению функционала, можно рассмотреть.
Римское правило. Тот, кто говорит, что Это не может быть сделано, никогда не должен мешать тому, кто Это делает.
Осень, ну вы поняли.
Зачем еще один код? А человек?
Здравствуйте, MikelSV, Вы писали:
MSV>Дата: 02.04.11 13:34 MSV>Вчера совершенно случайно начали обсуждать tuple и их реализацию в С++, может они шутили, но я занялся и вот что получилось.
MSV>
она вобще компилируется?
выравнивение учитывает?
MSV>Контроль за количеством переменных и типами оставляю на программиста, если он ошибется вызывается memcpy(0, 0, 1); мне показалось это достаточно прямолинейное сообщение об ошибке. Можно сделать что-нибудь попроще.
assert?
MSV>Таким же способом можно передавать туплы в функции. Запятые не прошли, пришлось использовать знаки +.
make_tuple(...)?
MSV>Хотелось бы узнать, есть ли еще реализации туплов. Про туплы на boost слышал. Мне не понравилось. Там каждый шаг нужно описывать.
Оказывается мноие удивляются char data[0];. Я с этим давно работаю, оно нормально компилируется и не занимает размера в структуре, а обращаться можно. Это неплохо используется, когда нужно разместить в памяти несколько структур содержащих текстовые данные неизвестной заранее длинны.
Это уже не привычные массивы, где элементы расставлены через четкие расстояния, здесь все определяется размером в unsigned int sz.
Компилятор на это выдает предупреждение, но работает без проблем.
NB>assert?
Да, assert(0); вполне подходит.
MSV>>Таким же способом можно передавать туплы в функции. Запятые не прошли, пришлось использовать знаки +. NB>make_tuple(...)?
Я старался уйти от вызова функций. Так же для каждого количества переменных в тупле нужно писать свою функцию. В принципе, вызов функции будет работать быстрее, так как сразу известны все переменные. В принципе make_tuple() без проблем реализуется в моем коде.
NB>std::tuple
Почитаю.
Римское правило. Тот, кто говорит, что Это не может быть сделано, никогда не должен мешать тому, кто Это делает.
Осень, ну вы поняли.
Зачем еще один код? А человек?
Здравствуйте, MikelSV, Вы писали:
MSV>Основной аргумент против этого кода: он не нужен, есть boost::tuple.
MSV>Простенько и со вкусом.
разве что со вкусом говна, к примеру у boost::tuple можно узнать размер на этапе компиляции с помощью boost::fusion::result_of::size, а ещё он нормально работает с полиморфными обьектами.
Здравствуйте, MikelSV, Вы писали:
MSV>Это перепост темы, по просьбам трудящихся, из форума исходники. За два дня на нее не было ни одного ответа, которых так хотелось. В следствии чего была высказана мысль написать еще раз в форум c++.
С уваженьем (Дата, Подпись)
Отвечайте нам, а то
Если вы не отзоветесь,
Мы напишем в "Спортлото"
--
Справедливость выше закона. А человечность выше справедливости.
Здравствуйте, night beast, Вы писали: MSV>>Вчера совершенно случайно начали обсуждать tuple и их реализацию в С++, может они шутили, но я занялся и вот что получилось.
MSV>>
Здравствуйте, MikelSV, Вы писали:
MSV>Два основных вопроса: нужен ли данный код и можно ли его использовать в реальных задачах?
его можно использовать в крайне узкоспециализированных задачах, на роль generic он не годится
1) он банально не скомпилируется, код некорректен с точки зрения стандарта
2) алгоритм, опирающийся на typeid::name непереносим, ибо никаких требований стандарт не возлагает на эти строки (к примеру, они все могут быть пустыми)
3) нет самых необходимых операторов — копирование и сравнивание (operator==)
4) проблемы с доступом к невыровненным данным
5) далеко не все сущности можно хранить через memcpy, так что набор поддерживаемых типов крайне ограничен
MSV>Контроль за количеством переменных и типами оставляю на программиста
это один из серьезнейших недостатков и его решают обычно обилием шаблонов
также было бы интересно, как клиенту класть значения в тупл и доставать. приведите, пожалуйста, код
я рекомендую вам проверить код на codepad.org прежде, чем выкладывать его
Здравствуйте, uzhas, Вы писали:
U>Здравствуйте, MikelSV, Вы писали:
MSV>>Два основных вопроса: нужен ли данный код и можно ли его использовать в реальных задачах? U>его можно использовать в крайне узкоспециализированных задачах, на роль generic он не годится U>1) он банально не скомпилируется, код некорректен с точки зрения стандарта U>2) алгоритм, опирающийся на typeid::name непереносим, ибо никаких требований стандарт не возлагает на эти строки (к примеру, они все могут быть пустыми) U>3) нет самых необходимых операторов — копирование и сравнивание (operator==) U>4) проблемы с доступом к невыровненным данным U>5) далеко не все сущности можно хранить через memcpy, так что набор поддерживаемых типов крайне ограничен
MSV>>Контроль за количеством переменных и типами оставляю на программиста U>это один из серьезнейших недостатков и его решают обычно обилием шаблонов U>также было бы интересно, как клиенту класть значения в тупл и доставать. приведите, пожалуйста, код U>я рекомендую вам проверить код на codepad.org прежде, чем выкладывать его
Код компилируется, в MSVS и g++, и мне кажется стандарт не против. на codepad.org он работать не захотел, похоже там стоит флаг считать все предупреждения ошибками. удалил char data[0]; заменил все d.data на (&d+1). предупреждение пропало. codepad.org нашел что-то еще. Там походу другой компилятор, надо поставить себе, разобраться, что он хочет.
Есть в стандарте способ получить уникальный идентификатор типа? может ссылка на структуру, или id? По идее что-то должно быть, переносимое, но я к сожалению не в курсе и знаю только про typeid.
Оператор копирования есть, но работает он достаточно интересным способом. Когда Tuple передается из/в функцию, вызывается оператор копирования и Tuple начинает вставлять данные в переменные. Вставка данных: Tuple(), a, b, c; Передача в функцию: Tuple(Tuple&t), установка флага вставки данных. Вставка данных в переменные: t, i, j, k; Боюсь это цена за мою реализацию без функций make_tuple() и прочих.
Проблемы с доступом к невыровненным данным не понятны. Могу предположить, что имеются в виду системы которые не могут работать с такими данными, тогда следует внести небольшие изменения в код и выровнять их.
Я слегка не разобрался, как лучше работать с данными. Есть три варианта: memcpy, перемещение и копирование. Это заложено в define TPLM — move и TPLC — copy. Полагаю более правильный вариант копировать данные, перемещение было бы быстрее( memcpy и memset(0); ), но есть шанс задеть глобальные данные.
Данные кладутся через: Tuple t; t + i; t + k + j; Для извлечения можно сделать функцию. void Out(){ adel=1; } Если Tuple передан в/из функции, будет вызван оператор копирования Tuple(Tuple&t) и флаг установится автоматически. Данные извлекаются так же: t + i; t + k + j;
--
Данный код адаптирован под задачи, которые я смог увидеть: Передача нескольких переменных из/в функцию. Я не очень представляю, какие операции понадобится выполнять с туплами. Я приложил все усилия, чтобы оптимизировать их именно под эти задачи. Я хотел исключить все явные вызовы функций, и кажется мне это удалось. Написать функции не проблема, полагаю даже нужно, они будут проще для понимания
Я вижу, что этот код еще в самом начале своего развития, есть множество задач под которые он не рассчитывался и не писалась реализация функционала.
Я бы хотел продолжить его разрабатывать, но мне нужны задачи, которые, надеюсь, предоставят те, кто использует туплы. Я бы хотел узнать о бо всех областях, в которых их можно применить.
Я постараюсь придерживаться своего варианта по мере возможностей, но уже вижу, что еще сильнее скачусь в шаблоны. Но все же надеюсь оставить такое же простое использование при решении простейших задач.
Римское правило. Тот, кто говорит, что Это не может быть сделано, никогда не должен мешать тому, кто Это делает.
Осень, ну вы поняли.
Зачем еще один код? А человек?
NB>>она вобще компилируется?
MSV>Оказывается мноие удивляются char data[0];. Я с этим давно работаю, оно нормально компилируется и не занимает размера в структуре, а обращаться можно. Это неплохо используется, когда нужно разместить в памяти несколько структур содержащих текстовые данные неизвестной заранее длинны. MSV>Это уже не привычные массивы, где элементы расставлены через четкие расстояния, здесь все определяется размером в unsigned int sz. MSV>Компилятор на это выдает предупреждение, но работает без проблем.
в Си для этого использовали char data[];
в Си++ массив нулевого размера -- распространенная методика получения ошибки времени компиляции.
MSV>>>Таким же способом можно передавать туплы в функции. Запятые не прошли, пришлось использовать знаки +. NB>>make_tuple(...)? MSV>Я старался уйти от вызова функций. Так же для каждого количества переменных в тупле нужно писать свою функцию. В принципе, вызов функции будет работать быстрее, так как сразу известны все переменные. В принципе make_tuple() без проблем реализуется в моем коде.
Здравствуйте, night beast, Вы писали:
NB>в Си для этого использовали char data[]; NB>в Си++ массив нулевого размера -- распространенная методика получения ошибки времени компиляции.
Реакция на char data[]; такая же как и на char data[0]; — Студия пишет ошибку, g++ молчит.
NB>__VA_ARGS__?
Не очень понятно, причем здесь это. не вижу, как оно может быть использовано.
Римское правило. Тот, кто говорит, что Это не может быть сделано, никогда не должен мешать тому, кто Это делает.
Осень, ну вы поняли.
Зачем еще один код? А человек?
Здравствуйте, MikelSV, Вы писали:
NB>>в Си для этого использовали char data[]; NB>>в Си++ массив нулевого размера -- распространенная методика получения ошибки времени компиляции. MSV>Реакция на char data[]; такая же как и на char data[0]; — Студия пишет ошибку, g++ молчит.
как получить в С++ такого же эффекта я не знаю (на самом деле оно в нем и не нужно)
NB>>__VA_ARGS__? MSV>Не очень понятно, причем здесь это. не вижу, как оно может быть использовано.
вы и есть за меня будете?
ага
не вижу, чем (TPL a + b + c) принципиально лучше чем MAKE_TPL(a,b,c)
Здравствуйте, night beast, Вы писали:
NB>Здравствуйте, MikelSV, Вы писали:
NB>>>в Си для этого использовали char data[]; NB>>>в Си++ массив нулевого размера -- распространенная методика получения ошибки времени компиляции. MSV>>Реакция на char data[]; такая же как и на char data[0]; — Студия пишет ошибку, g++ молчит.
NB>как получить в С++ такого же эффекта я не знаю (на самом деле оно в нем и не нужно)
студия (msvc2008) нормально компилит
и в Си и в Си++ режиме
такой код
Здравствуйте, jyuyjiyuijyu, Вы писали:
NB>>как получить в С++ такого же эффекта я не знаю (на самом деле оно в нем и не нужно)
J>студия (msvc2008) нормально компилит J>и в Си и в Си++ режиме J>такой код J>
Да, не подумал. На g++ тоже работает.
Я недолюбливаю __VA_ARGS__ за то, что они не работают в 2003 студии.
Римское правило. Тот, кто говорит, что Это не может быть сделано, никогда не должен мешать тому, кто Это делает.
Осень, ну вы поняли.
Зачем еще один код? А человек?
Здравствуйте, Sni4ok, Вы писали:
NB>>зря ты так. ну тренируется человек, кому от этого плохо?
S>человек же сам попросил оценок, тоесть он готов и хочет критику.
критика, это не "ваш код г*но", а "ваш код г*но, потому что ..."