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

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

14.07.2016, 23:27. Показов 1792. Ответов 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
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 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
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
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
18149 / 10731 / 2067
Регистрация: 27.09.2012
Сообщений: 27,035
Записей в блоге: 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
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
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
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,818
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
Ответ Создать тему
Новые блоги и статьи
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это дополнительная запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru