С Новым годом! Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.86/7: Рейтинг темы: голосов - 7, средняя оценка - 4.86
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499

Какой паттерн подойдет, чтобы избежать длинных ветвлений?

14.07.2016, 23:27. Показов 1710. Ответов 13
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
здравствуйте, есть код схематично такой:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class CTest_base {
public:
    CTest_base() : vec() {}
    virtual ~CTest_base() noexcept {}
    //something else
protected:
    std::vector<int> vec;
};
 
class CTest : public CTest_base {
public:
    CTest() : a(0) {}
    ~CTest() noexcept {}
    //something else
    void set() {
        if(a==2)
            vec.shrink_to_fit();
        else if(a==3)
            vec.clear();
        else if(a==4)
            vec.resize(5);
        else 
            vec.emplace_back(0);
    }
    void set_a(int&& a) {
        this->a = std::move(a);
    }
private:
    int a;
};
какой паттерн применить в таких случаях чтобы избегать длинных ветвлений в рантайме? шаблоны не подходят т.к. в рантайме вызывается set_a... observer и template method вроде не подходят... как быть?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
14.07.2016, 23:27
Ответы с готовыми решениями:

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

Какой паттерн использовать?
Какой паттерн использовать (и использовать ли) в такой ситуации: Существует множество разноклассовых объектов на тачскрин-экране, могущих...

Какой паттерн лучше применить?
Добрый день например в WPF приложении есть 3 Views. Каждая View содержит Control разного типа, пусть это будут кнопки(круглая, квадратная и...

13
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
14.07.2016, 23:33
Цитата Сообщение от tapochka Посмотреть сообщение
какой паттерн применить в таких случаях чтобы избегать длинных ветвлений в рантайме?
switch case ?
0
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499
14.07.2016, 23:35  [ТС]
Цитата Сообщение от hoggy Посмотреть сообщение
switch case
ооп-шное что-нибудь
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
14.07.2016, 23:38
Цитата Сообщение от tapochka Посмотреть сообщение
как быть?
как вариант - сделать какой-нибудь any с реализацией type erasure,
запихать туда std::function и сделать map/vector/array из any с разными "функциями" внутри.

Еще вариант - map/vector/array с std::function/функциями типа void(std::vector&).
Затем arr[a](vec);. Каждая "функция" вызывает что нужно у вектора.
1
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
14.07.2016, 23:39
tapochka, ООП-шное - это передавать не интовое состояние в класс, а Actor, у которого есть соответствующе определенная операция по работе с vec.
1
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
14.07.2016, 23:41
Цитата Сообщение от tapochka Посмотреть сообщение
ооп-шное что-нибудь
ну если вам нужен ооп ради ооп, и ради этого вы готовы просадить перфоманс,
замедлив работу без какой либо необходимости,
то можете использовать классический подход:

C++
1
2
3
4
5
std::map<key, std::unique_ptr<ICommand> > commands;
 
...
 
commands[a]->work();
а потом лепить наследников на каждый чих.

кода придется написать больше.
памяти жрать будет больше.
работать будет медленнее.

кстати, белая магия компилятора так же способна в некоторых случаях
представить свитч-кейс в виде ассоциативного массива.
вот только без потерь перфоманса.
1
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499
14.07.2016, 23:46  [ТС]
Цитата Сообщение от Croessmah Посмотреть сообщение
как вариант - сделать какой-нибудь any с реализацией type erasure,
запихать туда std::function и сделать map/vector/array из any с разными "функциями" внутри.
ну имелось ввиду не только с++... если любой ооп-поддерживаемый язык брать

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

Добавлено через 2 минуты
Цитата Сообщение от hoggy Посмотреть сообщение
ну если вам нужен ооп ради ооп, и ради этого вы готовы просадить перфоманс,
замедлив работу без какой либо необходимости,
ну просто в моем случае один метод ну слишком уродский получается через ветвления

Цитата Сообщение от hoggy Посмотреть сообщение
кстати, белая магия компилятора так же способна в некоторых случаях
представить свитч-кейс в виде ассоциативного массива.
да читал вроде всегда так компилятор поступает... не проверял правда

Добавлено через 1 минуту
Цитата Сообщение от DrOffset Посмотреть сообщение
tapochka, ООП-шное - это передавать не интовое состояние в класс, а Actor, у которого есть соответствующе определенная операция по работе с vec.
можете плз на коленках набросок кинуть?
0
Неэпический
 Аватар для Croessmah
18144 / 10728 / 2066
Регистрация: 27.09.2012
Сообщений: 27,026
Записей в блоге: 1
14.07.2016, 23:47
Цитата Сообщение от tapochka Посмотреть сообщение
можете плз на коленках набросок кинуть?
В принципе, тоже самое, что и hoggy привел.
Разница в деталях разве что.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
14.07.2016, 23:49
Цитата Сообщение от tapochka Посмотреть сообщение
ну просто в моем случае один метод ну слишком уродский получается через ветвления
если ключи идут строго друг за другом,
то можно сделать обычный вектор акторов std::function

C++
1
2
3
4
std::vector< std::function<void()> > actors;
 
actors.emplace_back(  [&vec](){ vec.shrink_to_fit();  }  );
actors.at(a)();
1
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499
14.07.2016, 23:57  [ТС]
вот думал что-то типа tag-dispatching... прикрутить бы(из инета код)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
namespace std {
  struct input_iterator_tag { };
  struct bidirectional_iterator_tag : input_iterator_tag { };
  struct random_access_iterator_tag : bidirectional_iterator_tag { };
 
  namespace detail {
    template <class InputIterator, class Distance>
    void advance_dispatch(InputIterator& i, Distance n, input_iterator_tag) {
      while (n--) ++i;
    }
 
    template <class BidirectionalIterator, class Distance>
    void advance_dispatch(BidirectionalIterator& i, Distance n, 
       bidirectional_iterator_tag) {
      if (n >= 0)
        while (n--) ++i;
      else
        while (n++) --i;
    }
 
    template <class RandomAccessIterator, class Distance>
    void advance_dispatch(RandomAccessIterator& i, Distance n, 
       random_access_iterator_tag) {
      i += n;
    }
  }
 
  template <class InputIterator, class Distance>
  void advance(InputIterator& i, Distance n) {
    typename iterator_traits<InputIterator>::iterator_category category;
    detail::advance_dispatch(i, n, category);
  }
}
Добавлено через 2 минуты
в моем случае просто идет работа с view, т.е. быстродействие совсем не обязательно... можно экспериментировать со свистелками-перделками
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
15.07.2016, 00:09
Цитата Сообщение от tapochka Посмотреть сообщение
можете плз на коленках набросок кинуть?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class CTest
    : public CTest_base
{
public:
    CTest() : a() {}
    ~CTest() noexcept {}
    //something else
    void set()
    {
        a(vec);
    }
    template <typename Actor>
    void set_a(Actor && ac)
    {
        a = std::move(ac);
    }
private:
    std::function<void(std::vector<int> &)> a;
};
Логика такая: если мы все равно задаем ключ операции внешним источником, то может быть сразу саму операцию и передавать извне?
1
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499
15.07.2016, 00:21  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Логика такая: если мы все равно задаем ключ операции внешним источником, то может быть сразу саму операцию и передавать извне?
слишком по-уродски получится... выражения трехэтажные получатся

спасибо, мысль понял... жаль только еще более элегантных решений нету...
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
15.07.2016, 00:32
Ну или (если уж от интового ключа никак не избавиться) как-то так:
В принципе и без std::function можно обойтись.
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class CTest
    : public CTest_base
{
public:
    CTest() : a() {}
    ~CTest() noexcept {}
    //something else
    void set()
    {
        a(vec);
    }
    void set_a(int key)
    {
        static void ( * op[])(std::vector<int> &) =
        {
             [](std::vector<int> & vec) {  vec.emplace_back(0); }
           , [](std::vector<int> & vec) {  vec.resize(5); }
           , [](std::vector<int> & vec) {  vec.clear(); }
           , [](std::vector<int> & vec) {  vec.shrink_to_fit(); }
        };
        a = op[key];
    }
 
private:
    void(* a)(std::vector<int> &);
};


Добавлено через 7 минут
Цитата Сообщение от tapochka Посмотреть сообщение
жаль только еще более элегантных решений нету
Да есть. Просто задача непонятная, допуски на задачу непонятные.
Универсального решения - да, нету. Но это всем известно.

Насчет:
Цитата Сообщение от tapochka Посмотреть сообщение
вот думал что-то типа tag-dispatching.
Посмотри-ка boost::variant и его static_visitor.
И вот сюда глянь: https://stackoverflow.com/ques... -functions
1
42 / 42 / 17
Регистрация: 25.04.2014
Сообщений: 499
15.07.2016, 00:57  [ТС]
Цитата Сообщение от DrOffset Посмотреть сообщение
Посмотри-ка boost::variant и его static_visitor.
а ведь да... я ж чутка разбирался... спасибо что напомнили

Добавлено через 18 минут
вот по этой статье разбирался, может кому пригодится
[вырезано]
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
15.07.2016, 00:57
Помогаю со студенческими работами здесь

На какой паттерн заменить switch?
Ситуация следующая: есть перечисление (5 элементов Type1 = 6, Type2 = 12....). Их интовое значение в итоге повлияет на размерность матрицы....

Какой структурный паттерн выбрать?
Задача поставлена следующим образом - &quot;С помощью шаблона проектирования обеспечить вывод на экран собственных инициалов, состоящих из...

Какой поведенческий паттерн выбрать?
Пишу на c#(Но это впринципе не важно) Есть задача: реализовать арифметические и логические операции с комплексными числами. Надо...

Посоветуйте, какой паттерн можно применить?
Ситуация следующая. Есть класс с набором методов, от него наследуется 3 класса, у каждого класса добавляются дополнительные поля и...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru