Russian Qt Forum

Программирование => С/C++ => Тема начата: __Heaven__ от Июль 18, 2014, 14:58



Название: Итераторы в последовательных контейнерах
Отправлено: __Heaven__ от Июль 18, 2014, 14:58
Всем доброго времени суток!
Последнее время я больше нацелен не только на результат выполнения определённых операций, но и на скорость их выполнения.
В связи с этим, меня стал интересовать вопрос использования итераторов.
Использование итераторов в ассоциативных контейнерах для меня выглядит как способ быстрого прохода по значениям контейнера.

В последовательных же контейнерах у меня непонятки.
Меня интересует проход по значениям. Раньше я без зазрения совести использовал конструкцию
Код:
for (int i = 0; i < vec.size(); i++)   // или для каждого третьего элемента i += 3
{
    ...
    vec.at(i);
    ...
}
Сточки зрения читабельности для меня этот вариант был удобен.
Сейчас же меня заинтересовала работа с итераторами, но я плохо себе представляю для чего они нужны в последовательных контейнерах, если существует указатель на начало массива данных. В интернете я нашёл, что итератор позволяет модифицировать объекты контейнера без влияния на сам итератор. Но, ведь при модифицировании контейнера можно поменять и указатель...
Объясните, пожалуйста, тёмному человеку преимущества итераторов.
Также интересует скорость работы с итераторами и с указателями.


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Old от Июль 18, 2014, 15:26
Не так давно был уже знатный срач на эту тему: http://www.prog.org.ru/topic_24541_0.html :)


Название: Re: Итераторы в последовательных контейнерах
Отправлено: __Heaven__ от Июль 18, 2014, 15:45
Не так давно был уже знатный срач на эту тему: http://www.prog.org.ru/topic_24541_0.html :)

Хохохо!  ;D и как же я это не нашёл!
Спасибо!


Название: Re: Итераторы в последовательных контейнерах
Отправлено: _Bers от Июль 18, 2014, 22:13
В целом, итераторы - просто паттерн "универсального" обхода любых контейнеров.

Суть паттерна: механизмы могут перебирать содержимое контейнера ничего не зная ни о его элементах, ни о нюансах работы контейнера.

То есть, они могут перебирать содержимое любых контейнеров, даже самых замороченных точно так же, как если бы это был какой нибудь обычный массив.

http://ideone.com/4wyh7u

Код:
#include <iostream>     // std::cout
#include <iterator>     // std::ostream_iterator
#include <algorithm>    // std::generate, std::remove
#include <vector>       // std::vector
#include <ctime>        // std::time
#include <cstdlib>      // std::rand, std::srand

using namespace std;

int main()
{
    //--- создаем и заполняем контейнер случайными данными   
    std::vector<int> data(5);
    std::generate(data.begin(), data.end(), [](){ return (std::rand()%100);}  );
   
    //--- выводим в консоль содержимое контейнера
    std::cout<<" ---1---\n";
    std::copy( data.begin(), data.end(), std::ostream_iterator<int>(std::cout, ", ") );
    std::cout<<'\n';

std::cout<<" ---2---\n";
    for (size_t i = 0, end = data.size() ; i!=end; ++i)
        cout << data[i] << ", ";
    std::cout<<'\n';
   
    std::cout<<" ---3---\n";
    for (auto i = data.begin(), end = data.end(); i!=end ; ++i)
        cout<< *i << ", ";
    std::cout<<'\n';


return 0;
}
Как видите в простых случаях использование итератора принципиально не отличается от индекса.
и как вы видите, stl-алгоритмы используют итераторы, что бы выполнять операции над любыми контейнерами независимо от их устройства.

Есть области, где паттерн "итератор" значительно облегчает жизнь.

Вот например: нужно пройтись по файловой системе, перебирая файлы и папки:

Код:
#include <iostream>
using namespace std;

#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;

int main()
{
    cout<<"WELLCOME TO EXAMPLE APPLICATION!\n";
    fs::path p = fs::current_path();

    std::vector< fs::path > files;
    std::copy( fs::directory_iterator(p), fs::directory_iterator(), std::back_inserter(files) );
    std::copy( files.begin(), files.end(), std::ostream_iterator< fs::path > (std::cout, "\n") );

}

Сначала положит в files список всех файлов и каталогов, а затем выведет в консоль.

Без итераторов данная процедура заняла бы значительно большее количество кода.




Название: Re: Итераторы в последовательных контейнерах
Отправлено: __Heaven__ от Июль 19, 2014, 15:10
Мда…
Пойду ка я книжку умную почитаю, ибо ничего я не знаю о лямбда функциях, а пример с фс вообще не понял…
Спасибо за ответ.


Название: Re: Итераторы в последовательных контейнерах
Отправлено: _Bers от Июль 19, 2014, 23:18
пример с фс вообще не понял…

Перебираем содержимое каталога программы, и выводим его на экран.

Вот рабочий пример в действии:
http://rextester.com/HUV66703

Тоже самое, но без использования алгоритмов stl:

http://rextester.com/PNAGF68674

Код:
#include <iostream>
using namespace std;

#include <boost/filesystem.hpp>

//псевдоним namespace
//используется для сокращения писанины
namespace fs = boost::filesystem;

int main()
{
    cout<<"WELLCOME TO EXAMPLE APPLICATION!\n";

    //каталог, где была запущена программа   
    fs::path p = fs::current_path();
    cout<<"current path: "<< p<<endl;

    //выводим содержимое этого каталога
    //если встречаем каталог - пишим, что каталог
    //если встречаем обычный файл - пишим, что файл
    cout<< "current directory contains:\n";
    for( fs::directory_iterator it(p), end;  it!=end; ++it  )
        cout << (fs::is_directory(*it)? "directory: " : "file: " )<< *it <<endl;

    //при этом пустой fs::directory_iterator означает конец каталога
    //именно ему равен созданный по дефолту итератор end
   
    //а само содержимое по итератору может быть либо файлом, либо каталогом, либо ссылкой, либо ...
    //в зависимости от ОС и её причуд
   
    //итератор позволяет единообразно итерироваться по элементам файловой системы независимо от того, чем именно являются эти элементы
    //и при необходимости - узнать подробности о природе элемента, на который указывает итератор
}


Название: Re: Итераторы в последовательных контейнерах
Отправлено: __Heaven__ от Июль 20, 2014, 09:08
Я проверил по скорости исполнения оба кода и получил, что второй, без использования stl алгоритмов, работает в 25 раз быстрее, хоть выводит информации больше.

Можно ли основываясь на этом сделать вывод, что использование stl алгоритмов пагубно влияет на скорость исполнения?


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Bepec от Июль 20, 2014, 09:28
Потому что в первом имеет место копирование :) Как известно, это самая нехорошая часть в таких вычислениях :) А во втором варианте успешно без этого обходятся :D


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Old от Июль 20, 2014, 09:31
Я проверил по скорости исполнения оба кода и получил, что второй, без использования stl алгоритмов, работает в 25 раз быстрее, хоть выводит информации больше.
Вы не забыли, что первый вариант запихивает пути в vector, который с этим справляется хуже всего.

Можно ли основываясь на этом сделать вывод, что использование stl алгоритмов пагубно влияет на скорость исполнения?
Нет. Примеры на столько не равнозначные, что их даже сравнивать нельзя.



Название: Re: Итераторы в последовательных контейнерах
Отправлено: Bepec от Июль 20, 2014, 09:33
Чтобы сравнить нужно взять и сравнивать перебор. Т.е. циклы обработки, без подготовки данных.


Название: Re: Итераторы в последовательных контейнерах
Отправлено: _Bers от Июль 20, 2014, 10:21
Я проверил по скорости исполнения оба кода и получил, что второй, без использования stl алгоритмов, работает в 25 раз быстрее, хоть выводит информации больше.

Можно ли основываясь на этом сделать вывод, что использование stl алгоритмов пагубно влияет на скорость исполнения?

Нельзя.

В первом примере в вектор помещаются все повстречавшиеся fs::path, что ко всему прочему приводит к постоянному реалоку вектора.И только потом содержимое вектора выводится в консоль.

Во втором - только перебор файловых объектов в цикле и вывод на экран.






Название: Re: Итераторы в последовательных контейнерах
Отправлено: Igors от Июль 22, 2014, 13:03
Вот рабочий пример в действии:
http://rextester.com/HUV66703

Тоже самое, но без использования алгоритмов stl:

http://rextester.com/PNAGF68674
Ну второй как-то "не сильно хуже" и, на мой взгляд, гибче. Понадобится напр обновлять индикатор и/или проверить отмену (юзверь нажал cancel) - и как это встроить в std::copy? А при незатейливом цикле этой проблемы нет. Вообще короткий, элегантный текст обоих примеров достигнут за счет использования мощностей буста, силу итераторов он не демонстрирует  :)


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Old от Июль 22, 2014, 13:30
Вообще короткий, элегантный текст обоих примеров достигнут за счет использования мощностей буста
Даааа, мощности там задействованы серьезные. :)

силу итераторов он не демонстрирует  :)
Потому что вы от них очень многого ждете. :)


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Igors от Июль 22, 2014, 14:09
Даааа, мощности там задействованы серьезные. :)
Очень даже серьезные. Я так вижу Вам не приходилось это в нативняке исполнять - выглядит примерно так (начало)
Код
C++ (Qt)
FSIterator iterator;
OSStatus error = FSOpenIterator(&ref, kFSIterateFlat, &iterator);
if (error) return false;
 
ItemCount maxCount = 10;
FSSpec FS[10];
 
while (true) {
error = FSGetCatalogInfoBulk(
iterator,
10, // ItemCount maximumObjects,
&maxCount, // ItemCount * actualObjects,
0, // Boolean * containerChanged,
kFSCatInfoNone, // FSCatalogInfoBitmap whichInfo,
0, // FSCatalogInfo * catalogInfos,
0, // FSRef * refs,
FS, // FSSpec * specs,
0 // HFSUniStr255 * names
);
if (error && error != errFSNoMoreItems) break;
Boolean aliasFileFlag, folderFlag;
 
for (int i = 0; i < maxCount; ++i) {
 OSErr err2 = IsAliasFile(FS + i, &aliasFileFlag, &folderFlag);
...
Главное что вот эту всю грязную работу за меня сделали - и на всех платформах, и за это я даже согласен с итераторами  :)


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Old от Июль 22, 2014, 15:03
Очень даже серьезные.
Да, вот это серьезность. :)

Я так вижу Вам не приходилось это в нативняке исполнять - выглядит примерно так (начало)
Скажу вам по секрету, но в нативняке для этого нужно использовать:
Код
C++ (Qt)
   DIR *dir;
   struct dirent *entry;
 
   dir = opendir("/");
   if (!dir) {
       perror("diropen");
       exit(1);
   };
 
   while ( (entry = readdir(dir)) != NULL) {
       printf("%d - %s [%d] %d\n",
           entry->d_ino, entry->d_name, entry->d_type, entry->d_reclen);
   };
 
   closedir(dir);
 
ну findfirst/findnext в крайнем случае, а это вы хрень какую-то написали. :)

И да, так я писал на C (года так до 93), как только у меня появился C++, я сразу сделал для него специальный класс и долгое время использовал его. А потом в boost сделали filesystem.


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Igors от Июль 22, 2014, 17:19
ну findfirst/findnext в крайнем случае, а это вы хрень какую-то написали. Улыбающийся
Не стоит резво судить о нативном коде платформы на которой никогда не работали  :)

Да, вот это серьезность. :)
Именно - даже под дулом автомата Вы не вернетесь у нативному коду. В этом нет ничего плохого - но ведь "концептуальная красота итераторов" здесь совершенно ни при чем  :)


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Old от Июль 22, 2014, 17:33
Не стоит резво судить о нативном коде платформы на которой никогда не работали  :)
А я резко и не сужу, там под капотом unix, а это значит opendir в нативе, а не эта высокоуровневые хрень, что вы привели. Понимаю, что вы такого натива не знаете.

Именно - даже под дулом автомата Вы не вернетесь у нативному коду.
Ерунда. Если понадобиться, то с удовольствием вернусь. Только я сделаю удобные классы, куда и спрячу весь натив, а не буду везде писать этот фарш.
Кстати, Армы сейчас к этому сильно располагают.

В этом нет ничего плохого - но ведь "концептуальная красота итераторов" здесь совершенно ни при чем  :)
Какой красоты вы от них ждете? :)


Название: Re: Итераторы в последовательных контейнерах
Отправлено: kambala от Июль 22, 2014, 18:16
2Igors: на Objective-C с его фреймворками пишется проще


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Igors от Июль 22, 2014, 18:43
Ерунда. Если понадобиться, то с удовольствием вернусь. Только я сделаю удобные классы, куда и спрячу весь натив, а не буду везде писать этот фарш.
Последние полгода активно избавляюсь от от таких удобных классов, так что про удовольствие не заливайте  :)

2Igors: на Objective-C с его фреймворками пишется проще
Да, Objective придется изучать и по многим др причинам.


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Old от Июль 22, 2014, 19:15
Последние полгода активно избавляюсь от от таких удобных классов, так что про удовольствие не заливайте  :)
Значит они у вас были такие "удобные". :)
Страшно представить, что там у вас было, если вы на это переходите и радуетесь этому:
Код
C++ (Qt)
FSIterator iterator;
OSStatus error = FSOpenIterator(&ref, kFSIterateFlat, &iterator);
if (error) return false;
 
ItemCount maxCount = 10;
FSSpec FS[10];
 
while (true) {
error = FSGetCatalogInfoBulk(
iterator,
10, // ItemCount maximumObjects,
&maxCount, // ItemCount * actualObjects,
0, // Boolean * containerChanged,
kFSCatInfoNone, // FSCatalogInfoBitmap whichInfo,
0, // FSCatalogInfo * catalogInfos,
0, // FSRef * refs,
FS, // FSSpec * specs,
0 // HFSUniStr255 * names
);
if (error && error != errFSNoMoreItems) break;
Boolean aliasFileFlag, folderFlag;
 
for (int i = 0; i < maxCount; ++i) {
 OSErr err2 = IsAliasFile(FS + i, &aliasFileFlag, &folderFlag);
...

Надеюсь никому не придется это переделывать в будущем. ;)


Название: Re: Итераторы в последовательных контейнерах
Отправлено: _Bers от Июль 22, 2014, 23:40
Ну второй как-то "не сильно хуже" и, на мой взгляд, гибче. Понадобится напр обновлять индикатор и/или проверить отмену (юзверь нажал cancel) - и как это встроить в std::copy?

Не очень понятно о чем речь. Но если я правильно понял, то вы можете использовать предикат.
http://www.cplusplus.com/reference/algorithm/copy_if/

А при незатейливом цикле этой проблемы нет.

Итераторы позволяют итерироваться универсально. Без итераторов - получаем зоопарк "конкретных случаев".
Это имеет кучу минусов. Я бы сказал - фатальных минусов. Серьезное переусложнение.

Вообще короткий, элегантный текст обоих примеров достигнут за счет использования мощностей буста, силу итераторов он не демонстрирует  :)

итератор - паттерн, который имеет место быть не только в отдельно взятой fs буста.
я могу продемонстрировать такого рода "элегантный текст" на кучке других механизмов.

Кстати:

Код:
...
some obj;
...
for(const auto& i: obj)
    cout<<i<<endl;

Незатейливый цикл реализуется за счет begin()/end() методов объекта любого типа, которые возвращают итераторы.
То есть, если реализовать итераторы для вашего кастомного механизма, то данный вид цикла сможет с ним работать.

Одной из разновидностей таких "кастомных" механизмов являются так называемые "вариативные типы данных".


Пример вариативного механизма:

    
Код:
    // в качестве значения можно посетить практически все что угодно
    Var v1;
    v1["hello"] = 10;
    v1["text"]  = "eos";
    v1["world"] = true;

    Var v;
    v["one"] = 10.5;
    v["two"] = v1;
    v["bar"] = "message";
    
    cout<<  v.ToHummanStyle()<<endl;
Цитировать
       map:
          'bar' "message"
          'one' 10.5
          'two' map:
            'hello' 10
            'text' "eos"
            'world' true


Вариативные типы данных позволяют пичкать их как простыми значениями разных типов, так и массивами, векторами, мапами, и тд и тп.

Теперь представьте себе: на входе вы получаете какой нибудь Variant, который содержит внутри себя нехилую такую древовидную структуру всяческих чевотов.

И как вы себе представляете обход такого дерева без итераторов?

С итераторами все просто:
Нет принципиальной разницы: обходить дерево файловой системы, встречая по пути папки (контейнерные типы), или файлы (примитивные типы-значения).

Разные контейнерные типы - да не проблема. Итераторам все равно пофигу как по ним по всем бегать.
Поэтому, вариативный тип без каких либо изменений или доработок уже поддерживает любые типы контейнеров, если они умеют стандартизированные итераторы.

Без итераторов задача стала бы очень нетривиальной - пришлось бы пасти все возможные случаи, и каждый такой случай обрабатывать отдельно.

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


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Bepec от Июль 22, 2014, 23:58
А если сократить предыдущего оратора:
Итератор это объект, абстрагирующий за единым интерфейсом доступ к элементам коллекции.

Он не силён, он не могуч. Он обеспечивает доступ и не более.

А вот обрабатывать каждый случай будет не он, а следующий аз ним код :)

PS все слова о сокращении кода - муть. Там будет тот же код, только спрятанный в классе :)


Название: Re: Итераторы в последовательных контейнерах
Отправлено: m_ax от Июль 23, 2014, 00:29
А вот обрабатывать каждый случай будет не он, а следующий аз ним код :)

PS все слова о сокращении кода - муть. Там будет тот же код, только спрятанный в классе :)

Чушь..( Не надо вводить людей в заблуждения подобными заявлениями.

Похоже вы так и не поняли о чём хотел сказать _Bers.. И не только он..
Но всё бестолку..(






Название: Re: Итераторы в последовательных контейнерах
Отправлено: _Bers от Июль 23, 2014, 00:37
PS все слова о сокращении кода - муть. Там будет тот же код, только спрятанный в классе :)

Код перебора элементов контейнера уже написан, и содержится в самих контейнерах.

Приведу пример:

Предположим, что есть некий универсальный тип данных, которые умеет принимать любые примитивные типы: int/float/etc

Код:
Value v1=10;
Value v2=10.5f;
Value v3=true;

Теперь:

Я делаю:

Код:
::std::vector<Value> myvec;

Поскольку, сам Value умеет работать с любыми прититивами, то я только что создал вектор "любых примитивов"

Код:
myvec.emplace_back(10);
myvec.emplace_back(true);

Теперь представьте себе, что Value умеет принимать не только "тип-значение", а вообще объекты любых типов.
наподобие boost::any

В этом случае ему станет возможным подсунуть контейнер "любых примитивов" :

Код:
Value val = myvec;
В точки присвоения объекта вариативному типу, отрабатывает шаблоно-конструкция, в который времени компиляции можно "детектить" наличие в типе методов begin/end

Так Value можно научить дергать контейнеры за итераторы, если они вообще есть.

Получаем: вариативный механизм, который не содержит ни строчки кода о том, как нужно перебирать контейнеры.
Весь этот код уже написан, и содержится в самих контейнерах, таких, как ::std::vector, или ::std::map

Мы лишь параметризуем эти контейнеры типом Value, и дергаем за их итераторы для перебора.

Теперь переименуем Value в Variant и получаем одну из многих моделей вариативного типа.

И если в какой то момент захочется добавить, например ::std::list, то мы можем сделать просто:

Код:
::std::list<Value> mylist;
Value val = mylist;

И пользоваться. Никаких доработок в самом Value делать не нужно, потому что ::std::list сам прекрасно знает как ему себя итерировать.


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Bepec от Июль 23, 2014, 10:30
Ну собственно это итератор и шаблоны. Вот теперь я действительно не понимаю что вы хотели сказать последним сообщением.

Дополняя итераторы шаблонами мы получаем мощный инструмент. Да, вы получаете результат из уже имеющегося контента (ммм... уже написанных инструментов).

Но что будет в случае с контейнером, не поддерживающим итераторы?



Название: Re: Итераторы в последовательных контейнерах
Отправлено: Igors от Июль 23, 2014, 11:33
Ну хорошо, давайте про  "контейнер любых типов". Есть древняя структура (в хвосте поста), менять ее нельзя т.к. она создается внешним редактором. Массив/контейнер таких структур "отображается" в массив существующих UI элементов. Смысл: имея массив структур + UI мы его запускаем без всякого доп кода, крутим пока не нажато Ok/Cancel и сливаем значения в выходную структуру. Таким образом никакого UI кода юзер не пишет. Давным-давно был написан совершенно лобовой код для всего этого, в псевдокоде выглядит так (ну конечно реально там совсем не QWidget - тогда Qt еще не успело родиться)

Код
C++ (Qt)
bool AcceptData( std::vector <CData> & data  )
{
for (size_t i = 0; i  < data.size(); ++i) {
  QWidget * w = GetWidget(i);     // берем UI элемент
  int type = GetWidgetType(w);    
 
// пошли разборки
  switch (type) {
    case edit_Text:
      switch (data[i].rmp_Type) {
        case TYPE_SFLOAT:
            float val = GetFloat(w);
            if (data[i].rmp_Flag & FLAG_BIT_LIMITED) {
               // проверка диапазона
            }
            // запись в выходную структуру
            break;
      }
  }
}
}
 
Затем все повторяется для др типов CData (TYPE_UFLOAT, TYPE_SLONG, TYPE_ULONG, TYPE_BOOLEAN, TYPE_OPTION, TYPE_RGB, TYPE_ARGB). Но это все только для контрола editText. Для всех др контролов - все по новой, т.е. еще ветки case. И это все прием данных из UI. Для их установки - еще код такого же объема. Понятно что надо все это как-то обобщить - но как?

Сама структура
Код
C++ (Qt)
struct CData
{
enum
{
TYPE_UNDEFINED,
TYPE_SFLOAT,
TYPE_UFLOAT,
TYPE_SLONG,
TYPE_ULONG,
TYPE_BOOLEAN,
TYPE_OPTION,
TYPE_RGB,
TYPE_ARGB,
TYPE_CUSTOM
};
 
enum
{
FLAG_BIT_LIMITED = 31,
FLAG_BIT_ANIMATE = 30
};
 
 
unsigned char rmp_Name[32];
long rmp_Flag;
unsigned long rmp_Type;
 
union
{
struct
{
double rmp_Value;
double rmp_Minimum;
double rmp_Maximum;
} valReal;
 
struct
{
long rmp_Value;
long rmp_Minimum;
long rmp_Maximum;
} valLong;
 
struct
{
long rmp_Value;
} valBool;
 
struct
{
long rmp_Value;
short rmp_ResourceID;
} valOption;
 
struct
{
unsigned short rmp_Red;
unsigned short rmp_Green;
unsigned short rmp_Blue;
unsigned short rmp_Alpha;
} valColor;
 
} channelData;
 
CustomData rmp_CustomData;
};
 

2_Bers Рассказываете Вы интересно и понятно, спасибо. Но все-таки "то примеры", а что будет на практике - неясно. Молодые-начитанные хотят по-быстрому чего-то слепить (пуская пыль в глаза теми же итераторами), в дедушкином коде копаться не хотят  :)


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Old от Июль 23, 2014, 15:58
А можно подробней?
Вот мы взяли нулевой элемент вектора data. По индексу взяли виджет, я так понимаю, из ui и спросили его тип - пусть это будет "Текстовая строка".
А дальше мы пытаемся из этой текстовой строки вытащить/установить данные в формате, заданном в элементе структуры CData?
А если виджет QLineEdit, а элемент TYPE_RGB, то нам нужно попробовать из строки виджета получить/установить цвет?

И огласите сразу все возможные типы виджетов.

P.S. И последний вопрос: этот код эту вермишель выше вы писали?  ::)


Название: Re: Итераторы в последовательных контейнерах
Отправлено: _Bers от Июль 23, 2014, 22:59
Igors,мне не понятна идея.

Приходит какой то массив данных.

Берется i-й виджет.

Для него выясняется числовой идентификатор типа.
Выясняется числовой идентификатор типа i-го элемента данных.

Для конкретного числового идентификатора типа виджета и конкретного числового идентификатора элемента данных что-то делается....


Что? Не понятно.. Не понятно почему именно так делается.

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

Кстати:

Код:
switch (data[i].rmp_Type) {
         case TYPE_SFLOAT:
             float val = GetFloat(w);
             if (data[i].rmp_Flag & FLAG_BIT_LIMITED) {
                // проверка диапазона
             }

можно заменить на:

Код:
switch (data[i].rmp_Type) {
         case TYPE_SFLOAT:
             float val = GetFloat(w);
             if (TYPE_SFLOAT & FLAG_BIT_LIMITED) {
                // проверка диапазона
             }

Если я правильно понял нотацию, то FLAG_BIT_LIMITED является константой. Следовательно все выражение:
Код:
TYPE_SFLOAT & FLAG_BIT_LIMITED
Является константой.

Условие определенно получается лишнее...



Название: Re: Итераторы в последовательных контейнерах
Отправлено: _Bers от Июль 23, 2014, 23:29
Но что будет в случае с контейнером, не поддерживающим итераторы?

Если тип не поддерживает стандартный дизайн итераторов, то он интерпритируется не как контейнер, а как обычный примитив.

Код:
int i = 10;   //<---- не умеет итераторы

Value v = i;  //<--- Value считает, что ему подсунули "не_контейнер"

...

Some obj; //<---- не умеет итераторы
v = obj;  //<--- Value считает, что ему подсунули "не_контейнер"


Вариант может просто хранить примитивы, но он не будет пытаться итерироваться внутри их.


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Bepec от Июль 24, 2014, 07:17
Спасибо за ответ - думал тут уже забыли о вопросе :)
Собственно как я и думал.


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Igors от Июль 24, 2014, 08:23
Вот мы взяли нулевой элемент вектора data. По индексу взяли виджет, я так понимаю, из ui и спросили его тип - пусть это будет "Текстовая строка".
А дальше мы пытаемся из этой текстовой строки вытащить/установить данные в формате, заданном в элементе структуры CData?
Да

А если виджет QLineEdit, а элемент TYPE_RGB, то нам нужно попробовать из строки виджета получить/установить цвет?
Нет, совместимость UI и опиcаний проверяется 1 раз на старте

И огласите сразу все возможные типы виджетов.
TYPE_SFLOAT   EditText
TYPE_UFLOAT   EditText
TYPE_SLONG    EditText
TYPE_ULONG    EditText
TYPE_BOOLEAN CheckBox
TYPE_OPTION   Popup
TYPE_RGB       ColorBox (no alpha)
TYPE_ARGB     ColorBox (with alpha)
TYPE_CUSTOM  "complex control" напр график

P.S. И последний вопрос: этот код эту вермишель выше вы писали?  ::)
Нет. Несмотря на всю свою уродливость этот код работает минимум 15 лет и делает все что требуется. Поэтому и живет

Для конкретного числового идентификатора типа виджета и конкретного числового идентификатора элемента данных что-то делается....

Что? Не понятно.. Не понятно почему именно так делается.
Смысл - запуск UI без написания какого-либо кода юзером. Он его готовит интерактивно рисуя контролы и создавая "дескриптор параметра" (CData) для каждого контрола. Отсюда ясно что делается

AcceptData - вызывается когда UI запущено, данные изменены и нажата кнопка Ok. Если данные невалидны нужно дать отлуп с объяснением причины (показать min, max, default). Иначе вылить данные (в char *)

SetupData - все наоборот, зарядить данные в UI

DefailtData - зарядить данные используя default в дескрипторах

И.т.д.


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Old от Июль 24, 2014, 09:56
Нет, совместимость UI и опиcаний проверяется 1 раз на старте
Если тип однозначно ассоциируется с виджетом, то лучше идти по типам данных, проверять тип виджета и если он подходящий устанавливать/читать данные.

Код
C++ (Qt)
bool AcceptData( std::vector <CData> & data  )
{
   for( size_t i = 0; i  < data.size(); ++i )
   {
       QWidget * w = GetWidget(i);     // берем UI элемент
       int type = GetWidgetType(w);    
       switch( data[ i ].rmp_Type )
       {
       case TYPE_SFLOAT:
           assert( type == edit_Text );    // Тип виджета должен быть однозначно QLineEdit
            if (data[i].rmp_Flag & FLAG_BIT_LIMITED) {
               // проверка диапазона
            }
            // запись в выходную структуру
            break;
 
       }
   }
}
 

А если перейти с C на C++, то можно легко избавится от этого большого свитча + можно будет легко добавлять другие типы без переделки всей системы.


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Igors от Июль 24, 2014, 14:08
Если тип однозначно ассоциируется с виджетом, то лучше идти по типам данных, проверять тип виджета и если он подходящий устанавливать/читать данные.
Такая "перестановка сомножителей" на принципиальное решение не тянет

А если перейти с C на C++, то можно легко избавится от этого большого свитча + можно будет легко добавлять другие типы без переделки всей системы.
Так давайте переходить - это и было предложено для обсуждения  :)

Да, на всякий случай: вход/выход (данные что устанавливаются в UI и запоминаются из него) = просто поток. Напр в QDataStream в терминах Qt. Этот (сохраненный) поток подается на вход расчетной части которая знает ту же форматку. До первого сохранения поток создается из дефаултов форматки 


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Old от Июль 24, 2014, 14:45
Такая "перестановка сомножителей" на принципиальное решение не тянет
Зато она избавляет от бесполезных внутренних свитчей по типам для каждого виджета - код уменьшится раза в два.

Так давайте переходить - это и было предложено для обсуждения  :)
Так давайте. :)
Такие задачки задают школьникам после прочтения им глав о наследовании и виртуальных функциях, кроме этого ничего из C++ не надо.
Или ждете готового решения?


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Igors от Июль 24, 2014, 15:38
Зато она избавляет от бесполезных внутренних свитчей по типам для каждого виджета - код уменьшится раза в два.
Да нисколько, напр связка type_EdtText + TYPE_SFLOAT как была так и осталась. Ведь пишутся только нужные ветки case, напр для type_Popup будет только TYPE_OPTION

Такие задачки задают школьникам после прочтения им глав о наследовании и виртуальных функциях, кроме этого ничего из C++ не надо.
Ну и что этим достигается? Кусочки свитча переносятся в методы классов, но экономии-то никакой. "Зато" надо наделать кучу сомнительных мелких классов + как-то отконвертить исходную структуру которая не виртуальна. Говоря "более официально" попытка наследования/обобщения для слабосвязных классов явно неудачна.

Или ждете готового решения?
Спесь поубавьте - опять вылезла  :)


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Old от Июль 24, 2014, 15:48
Да нисколько, напр связка type_EdtText + TYPE_SFLOAT как была так и осталась.
Посмотрите на мой кусок кода и на ваш. В моем внутреннего свитча нет вообще, как совершенно бесполезного.

Ну и что этим достигается? Кусочки свитча переносятся в методы классов, но экономии-то никакой.
А какую экономию вы ждали? Если что-то должно быть выполнено, то должен быть код это выполняющий.
Зато не будет нескольких больших свитчей в функциях установки и чтения данных, и не будет нужды при добавлении новых типов лезть в эти свитчи и что-то добавлять, и не получиться забыть в одну функцию ветку добавить, а в другую нет, и читаться все будет легко и просто (в отличие от этого треша).
К тому же, все числовые поля можно попробовать сделать одним шаблоном, но тут будет зависеть от возможностей виджета строки.

Говоря "более официально" попытка наследования/обобщения для слабосвязных классов явно неудачна.
Они не слабосвязанные, а прямо таки дети родные - это все поля данных (можно их так назвать).

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


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Igors от Июль 25, 2014, 10:35
Тогда предлагая, что то обсудить показывайте сразу ваши мысли, тогда будет понятно, что вы хотите разобраться, а не выхватить решение на халяву.
Ну что Вы такой "примитивно-жадный" :) У меня и в мыслях не было задействовать Вас в корыстных целях. Даже если (предположим) я получу идеальный ответ - вряд ли я буду что-то переделывать, по принципу "работает - не лезь". Но вот если в след раз возникнет аналогичная ситуация (что вполне вероятно) - буду делать "по уму", а не свитчеваться. А Вы вцепились в несущественные детали, типа как улучшить свитч - это не заслуживает обсуждения.

Рассмотрим небольшую подзадачу: контроль диапазона. Проверяем лежит ли введенное юзером значение в заданном диапазоне, если нет то предъявляем диалог где указаны min/max/default. Все данные для этого есть. Хотелось бы написать так
Код
C++ (Qt)
for (size_t i = 0; i < data.size(); ++i) {
...
if (!ValidRange(data[i], currentValue)) return false;
 
Тогда что делать в ValidRange ?
Код
C++ (Qt)
template <class T>
bool ValidRange( const CData & param, T & value )
{
if (!param.rmp_Flag & FLAG_BIT_LIMITED) return true;  // нет ограничений на диапазон
switch (param.rmp_Type) {
  case TYPE_SFLOAT:
  case TYPE_UFLOAT:
    if (value >= param.valReal.rmp_Minimum && value <= param.valReal.rmp_Maximum) return true;
    return DoModalDialog(value, param.valReal.rmp_Minimum, param.valReal.rmp_Maximum, param.valReal.rmp_Value> MODE_REAL);
 
  case TYPE_SLONG:
  case TYPE_ULONG:
    if (value >= param.valLong.rmp_Minimum && value <= param.valLong.rmp_Maximum) return true;
    return DoModalDialog(value, param.valLong.rmp_Minimum, param.valLong.rmp_Maximum, param.valLong.rmp_Value, MODE_LONG);
 
  default: return true;
}
}
И с общностью по-прежнему хреновато. Сам по себе диалог обобщается прекрасно - но там надо показывать или целые числа или с точкой. И опять вылазит свитч. Выделив ValidRange мы ничего особенного не достигли - ну двигаем свитчи туда-сюда. Возможно стоит сделать template выдачи min/max/default

А как хороши темплейты на простых примерах! Впрочем и этот не выглядит слишком сложным. Да, и где же юный энтузиаст шаблонной магии? Как всегда, занят с собачкой...


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Old от Июль 25, 2014, 10:49
И с общностью по-прежнему хреновато. Сам по себе диалог обобщается прекрасно - но там надо показывать или целые числа или с точкой. И опять вылазит свитч.
Так вы ничего не обобщаете.
Сделайте классы на каждый тип данных (для примера это для long знаковых и беззнаковых):
Код
C++ (Qt)
typedef quint64         FlagType;
 
class Field
{
public:
       explicit Field( const QString &name, FlagType flags ) : m_name( name ), m_flags( flags ) {}
 
       virtual void            setData( QWidget *w ) = 0;
       virtual void            getData( QWidget *w ) = 0;
 
private:
       QString         m_name;
       FlagType        m_flags;
};
 
class LongField : public Field
{
public:
       explicit Field( const QString &name, FlagType flags, long value, long min, long max, bool sign ) :
               Field( name, flags ), m_value( value ), m_min( min ), m_max( max ), m_sign( sign ) {}
 
       virtual void            setData( QWidget *w )
       {
 
       }
 
       virtual void            getData( QWidget *w )
       {
             // Проверили, что ввел пользователь и выдали диалог
       }
 
private:
       long            m_value;
       long            m_min;
       long            m_max;
       bool            m_sign;
};
 
   

А как хороши темплейты на простых примерах!
А как хорошо говнокодиться с свитчем... Ну вы в курсе. :)

Да, и где же юный энтузиаст шаблонной магии? Как всегда, занят с собачкой...
Тема настолько детская, что найдётся мало желающих пережовывать элементарщину.


Название: Re: Итераторы в последовательных контейнерах
Отправлено: m_ax от Июль 25, 2014, 12:01
Цитировать
Код
C++ (Qt)
for (size_t i = 0; i < data.size(); ++i) {
...
if (!ValidRange(data[i], currentValue)) return false;
 

Код
C++ (Qt)
template <class T>
bool ValidRange( const CData & param, T & value )
{
if (!param.rmp_Flag & FLAG_BIT_LIMITED) return true;  // нет ограничений на диапазон
switch (param.rmp_Type) {
  case TYPE_SFLOAT:
  case TYPE_UFLOAT:
    if (value >= param.valReal.rmp_Minimum && value <= param.valReal.rmp_Maximum) return true;
    return DoModalDialog(value, param.valReal.rmp_Minimum, param.valReal.rmp_Maximum, param.valReal.rmp_Value> MODE_REAL);
 
  case TYPE_SLONG:
  case TYPE_ULONG:
    if (value >= param.valLong.rmp_Minimum && value <= param.valLong.rmp_Maximum) return true;
    return DoModalDialog(value, param.valLong.rmp_Minimum, param.valLong.rmp_Maximum, param.valLong.rmp_Value, MODE_LONG);
 
  default: return true;
}
}
 

Я бы сделал проще, через специализацию шаблонов (как альтернатива наследованию) например так

Код
C++ (Qt)
typedef long TYPE_SLONG;
typedef unsigned long TYPE_ULONG;
typedef float TYPE_FLOAT;
 
template<class T, class Container>
class RangeValidator
{};
 
template <class Container>
class RangeValidator<TYPE_ULONG, Container>
{
public:
   RangeValidator(const Container & container) : _container(container) {}
 
   template <class T>
   bool isValid(const T & value) const
   {
       typedef typename Container::value_type value_type;
       auto it = std::find_if(_container.begin(), _container.end(), [&](const value_type & param) -> bool
       {
           return (value >= param.valLong.rmp_Minimum && value <= param.valLong.rmp_Maximum);
       }
       );
 
       if (it != _container.end())
       {
           // Сообщаем о проблемах.. и выходим..
       }
 
       return true;
   }
 
private:
   const Container & _container;
};
 

И если понадобится вдруг какой ещё тип данных, то нужно лишь реализовать для него свою специализацию RangeValidator..   


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Igors от Июль 26, 2014, 11:48
Сделайте классы на каждый тип данных (для примера это для long знаковых и беззнаковых):
Ага, а для типов с точкой будет еще точно такой же класс? И только потому что там long а здесь double. И чего Вы льете туда же и все подробности UI? Где же пресловутое разделение бызнес-логики? Да и флажок signed выглядит как "попытка уползти"  :), никакой идейностью не пахнет 

Тема настолько детская, что найдётся мало желающих пережовывать элементарщину.
Это справедливо только по отношению к предложенному Вами решению :) Наверное Вы и сами осознали его минусы - много каких-то классов, дубляж кода налицо, создание нового класса при первой же необходимости...

Я бы сделал проще, через специализацию шаблонов (как альтернатива наследованию) например так
TYPE_SLONG и др - это числовые константы используемые внешним редактором, менять ее нельзя. И не понял что Вы обобщаете если юзается valLong? Или имеется ввиду это надо повторить для др типов? Это как-то не привлекает, и тогда причем здесь find_if, этим должен заниматься вызывающий.

А вообще специализация шаблонов напрашивается. Может не связываться с самой форматкой, а подавать ее как аргумент в темплейтщину, напр
Код
C++ (Qt)
СParam <double> param(CData[i]);
А CParam уже как-то обобщать. Но это просто "мысли вслух"


Название: Re: Итераторы в последовательных контейнерах
Отправлено: _Bers от Июль 26, 2014, 12:37
Я так и не понял тз.


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Old от Июль 26, 2014, 12:47
Ага, а для типов с точкой будет еще точно такой же класс? И только потому что там long а здесь double.
Секундочку, это вы нас убеждаете, что вам нужно для целых и плавающих чисел показывать разные диалоги... А так все числа (знаковые/беззнаковые/целые/плавающие) можно положить в один шаблонный класс и не мучатся.

И чего Вы льете туда же и все подробности UI?
А вы не лейте туда UI, а посылайте сигнал (любым удобным для вас способом), в обработчике которого и показывайте диалоги. Думайте.

Где же пресловутое разделение бызнес-логики?
Так вы не делайте влоб, что за привычка. Я вам идею показываю, а вы на нее смотрите как на готовое решение и сокрушаетесь что вам не очень подходит. Подумайте, доработайте.

Это справедливо только по отношению к предложенному Вами решению :)
Повторюсь, это идея, которую нужно понять и развить. /* Но боюсь дальше решения в лоб со свитчами (эталон детской некомпетентности) вам не уползти. */

много каких-то классов
Классов ровно столько, сколько нужно для обработки всех типов данных и с появлением новых типов - достаточно добавить новый класс.

дубляж кода налицо
В каком месте? Покажите.

создание нового класса при первой же необходимости...
Вот! Это главная идея объектно-ориентированных языков программирования, которую вы никак не хотите понять. :)


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Old от Июль 26, 2014, 13:53
Я так и не понял тз.
В данном случае это практически не реально. :)
Никакого ТЗ нет, даже требований никаких нет и по ходу обсуждения будут придумываться новые условия и требования.
Просто вбрасывайте как поняли и будем развлекаться дальше. :)


Название: Re: Итераторы в последовательных контейнерах
Отправлено: _Bers от Июль 26, 2014, 14:13
Никакого ТЗ нет, даже требований никаких нет и по ходу обсуждения будут придумываться новые условия и требования.
Просто вбрасывайте как поняли и будем развлекаться дальше. :)

Вообще никак не понял.

В частности: есть кнопочки (гуй), есть логика (обработка каких то данных по нажатию на кнопку).
Мне не понятно, какое отношение одно имеет к другому?

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

Я вообще не понял, зачем был нужен цикл со свитчами. Не понял, в чем заключается суть его работы



Название: Re: Итераторы в последовательных контейнерах
Отправлено: Old от Июль 26, 2014, 14:25
Вообще никак не понял.
Все это для того, что бы дать пользователю возможность создавать UI без написания кода и соответственно перекомпиляции всей системы.
Например, пользователь написал скрипт, которому для работы нужно задать три параметра (два числа и цвет). Пользователь рисует в том же дизайнере диалог, состоящий из двух QLineEdit и ColorSelector и создает коллекцию структур, в которых указаны начальные значения для чисел, диапазоны, начальный цвет и т.д.
Эту коллекцию и UI-файл с диалогом передается движку, который создает диалог, устанавливает все параметры и показывает его пользователю, тот задает нужные параметры и жмет Ok, движок сохраняет их обратно в коллекцию и завершается. Скрипт берет заданные пользователем данные и выполняется.


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Igors от Июль 26, 2014, 16:00
Все это для того, что бы дать пользователю возможность создавать UI без написания кода и соответственно перекомпиляции всей системы.
Например, пользователь написал скрипт, которому для работы нужно задать три параметра (два числа и цвет). Пользователь рисует в том же дизайнере диалог, состоящий из двух QLineEdit и ColorSelector и создает коллекцию структур, в которых указаны начальные значения для чисел, диапазоны, начальный цвет и т.д.
Эту коллекцию и UI-файл с диалогом передается движку, который создает диалог, устанавливает все параметры и показывает его пользователю, тот задает нужные параметры и жмет Ok, движок сохраняет их обратно в коллекцию и завершается. Скрипт берет заданные пользователем данные и выполняется.
Совершенно верно, Вы достаточно сообразительный паренек (только с излишним самомнением). Ну правда подхватывает данные не скрипт, а С код - но не суть. Все равно есть контейнер "форматок" созданный извне + контейнер UI айтемов + сам поток (коллекция) значений. Вот и надо перегонять данные туда и обратно.


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Old от Июль 26, 2014, 16:12
Совершенно верно, Вы достаточно сообразительный паренек (только с излишним самомнением).
За паренька - спасибо. Давненько меня не называли пареньком, как-то не у всех поворачивается язык назвать сорокалетнего дядю - "пареньком". :)
Да и на сообразительность пока не жаловался. :) А вот ответить вам тем же, я к сожалению, не могу. Все приходится вам разжевывать и на пальцах показывать. ;)


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Igors от Июль 26, 2014, 17:25
.. назвать сорокалетнего дядю - "пареньком". :)
До дяди там еще далековато. у Вас все время вскипает юношеский пыл - впрочем это хорошо (увы, у меня это давно потеряно)

Все приходится вам разжевывать и на пальцах показывать. ;)
Так я ж "старый ретроград"  :)

2_Bers я, право, удивлен, задача довольно стандартная, термин "дескриптор параметра" достаточно известен. Что неясно - я постараюсь объяснить пополнее


Название: Re: Итераторы в последовательных контейнерах
Отправлено: _Bers от Июль 26, 2014, 17:32

Все это для того, что бы дать пользователю возможность создавать UI без написания кода и соответственно перекомпиляции всей системы.

Нужно что то типа QML?

Если бы я решил изготовить собственную гуевую систему, то использовал бы идею "все  - есть виджет".

Суть которой - единственный класс виджет реализует технику "виджет в виджете", и таки образом "из коробки" умеет трансформироваться в великое многообразие различных "конкретных виджетов" без необходимости дописывать код.

Пример:

Код:
auto form = 
  Form::create("form")
    .size(10,10)
    .position(100,100)
    .title("Form")  
    .widget<Box>("box1")
      .size(10,10)
      .position(100,100)
      .widget<Label>("label1")
        .size(10,10)
        .position(100,100)
        .text("this is label")
      .init()
    .init()
    .widget<Box>("box2")
      .size(10,10)
      .position(100,100)
    .init()
  .show();

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

В любой момент времени можно заменить значение любого "свойства" порожденного виджета в рантайме.

Проблема может возникнуть только при необходимости добавить принципиально новые "базовые свойств" самого виджета.

Эту проблему можно решать по разному.

Одно из довольно интересных решений - в специальном xml-подобном файле описывается название свойства, и его поведение:
"что будет происходить если..."

в качестве источника данных выступают примитивные типы - обычные int/float/string/etc
(привет, вариант!)

Другие виджеты смогут "цеплять" новое доступное свойство по его символьному имени.

резюмируя: виджет - это просто коробка так называемых "свойств".
(привет, компонентная система!)

Коллекция доступных "свойств" может создаваться либо в нативном коде, либо в скриптах.
Разные виджеты - это на самом деле один и тот же виджет, просто с разным набором свойств.

Свойства, которые повесили на один виджет могут "общаться" друг с другом посредством системы сообщений.
И в соотвествии со своей бизнес-логикой выполнять некоторые действия.

В качестве переменных с которыми могут захотеть работать свойства, можно передавать вариантивный тип данных.
Потому что он поддерживает все фундаментальные типы, и с его помощью можно передавать динамические структуры любой сложности.

Вариантивный тип так же можно использовать для связки "свойства порожденного в скриптах" с нативным кодом с++.
Тогда "динамичность" вариативного типа позволит установить полноценное общение между "скриптом" и "нативным кодом" без необходимости перекомпилировать все приложение.



Название: Re: Итераторы в последовательных контейнерах
Отправлено: Old от Июль 26, 2014, 17:34
До дяди там еще далековато. у Вас все время вскипает юношеский пыл - впрочем это хорошо (увы, у меня это давно потеряно)
Спасибо, спасибо. :)
Если я в свои годы сохранил юношеский пыл, то это несомненно хорошо.

Так я ж "старый ретроград"  :)
Ретроград отвергает все новое, а вы интересуетесь, но... при малейшей сложности/необходимости подумать - сдуваетсь. А после ваше традиционное: "Что я не понимаю/не умею, то не нужно и даже очень вредно, причем для всех." :)
/* Это кстати говорит о комплексе. */


Название: Re: Итераторы в последовательных контейнерах
Отправлено: _Bers от Июль 26, 2014, 17:35
я, право, удивлен, задача довольно стандартная, термин "дескриптор параметра" достаточно известен. Что неясно - я .постараюсь объяснить пополнее

С ваших слов задача была мне не понятна.

Если я сейчас правильно понял: вы хотите из текстового описания загрузить готовый layout.
То бишь формочку на экране из текстового файлика.

Я знаю несколько способов. Ни один из них не использует свитч-кейс. И все  позволяют порождать новые виджеты без необходимости перекомпиляции гуи-библиотеки.

Правда эта тема не имеет ни малейшего отношения к итераторам.

ps/ итераторы могут пригодиться, например, что бы предоставить пользователям возможность по простому, легко и безгемморойно рекурсивно пробежаться по всем чаилдам конкретного виджета.


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Igors от Июль 26, 2014, 18:11
Если я сейчас правильно понял: вы хотите из текстового описания загрузить готовый layout.
То бишь формочку на экране из текстового файлика.
Почему из текстового? Редактор дескрипторов/описаний никто не писал - взяли готовый из Mac OS Resourcerer), он там был еще до прихода линукса. Впрочем это непринципиально - так или иначе есть описание/дескриптор параметра (форматка)

Я знаю несколько способов. Ни один из них не использует свитч-кейс. И все  позволяют порождать новые виджеты без необходимости перекомпиляции гуи-библиотеки.
Здесь не ставится задача что-то порождать, т.е. вполне достаточно неск базовых/имеющихся контролов. Задача принимать/выливать введенные значения в поток (конечно используя форматку)

Правда эта тема не имеет ни малейшего отношения к итераторам.
Не имеет, навеяно Вашим "умеет принимать примитивные типы" - ну а так ли уж это примитивно?  :)


Название: Re: Итераторы в последовательных контейнерах
Отправлено: _Bers от Июль 26, 2014, 19:19
Почему из текстового?
Здесь не ставится задача что-то порождать
ну а так ли уж это примитивно?  :)

Вы определитесь что именно вам нужно.
Смысли, какой именно вопрос вы хотите задать лично мне, или другим участникам ветки.

Пока получается - есть клюкало. клюкало работает. клюкало не нужно менять. Так уж ли примитивно работает клюкало?



Название: Re: Итераторы в последовательных контейнерах
Отправлено: Igors от Июль 26, 2014, 19:34
Пока получается - есть клюкало. клюкало работает. клюкало не нужно менять. Так уж ли примитивно работает клюкало?
Да хотя бы и так (и даже неважно что Вы имеете ввиду под "клюкало"). Есть код который хотя и работает - но выглядит просто ужасно. Как переписать его грамотно? Как действовать в след раз в аналогичной ситуации? Это нормальный вопрос(ы), есть что предложить - я Вас внимательно слушаю.


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Bepec от Июль 26, 2014, 22:27
Переписать ради переписывания - это уже на грани идеального программирования. У вас видимо много времени :)


Название: Re: Итераторы в последовательных контейнерах
Отправлено: gil9red от Июль 26, 2014, 22:46
Переписать ради переписывания - это уже на грани идеального программирования. У вас видимо много времени :)

Многие программисты перфекционисты :)


Название: Re: Итераторы в последовательных контейнерах
Отправлено: Bepec от Июль 27, 2014, 08:35
Я тоже так хочу. Но времени нет :D