Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

Разработать архитектуру программы управления роботом - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Можно ли вывести сразу 2 значения int из функции через return? http://www.cyberforum.ru/cpp-beginners/thread1565004.html
Можно ли вывести сразу 2 значения из функции int через return ? Например функция находит X1 и X2 из квадратного уравнения, и может ли она сразу передать 2 значения ?
C++ Дополнить програму. Вывести элемент по величине Есть програма. В которую я ввожу размер массива и заполняю его числами. Первое число находится по центру, все больше перед ним, все меньше после него. # include <iostream> using namespace std; ... http://www.cyberforum.ru/cpp-beginners/thread1565000.html
C++ Построение класса для работы с односвязным списком
При решении необходимо, без использования STL, описать класс, который используется для представления элементов а) массива с фиксированным количеством элементов; б) динамической структуры данных....
Убрать из строки пробелы, если их более одного подряд C++
Добрый день, дорогие друзья. Хочу попросить у вас помощи. Нужно написать программу на языке C++. Задача программы: в заданной строке с нулевым завершителем убрать пробелы, если их более одного...
C++ Как поменять местами элементы в бинарном дереве? http://www.cyberforum.ru/cpp-beginners/thread1564973.html
Доброго времени суток! Имеется бинарное дереве, описанное вот так: struct tree { char info; struct tree *left; struct tree *right; }; Нужно поменять местами корневой и максимальный...
C++ Матрица в с++ Разработать схему алгоритма и написать программу на языке С++, которая выполняет (сложность задачи избирается преподавателем): а) для парных вариантов - чтение, для нечетных - запись значений... подробнее

Показать сообщение отдельно
hoggy
Нарушитель
6588 / 2769 / 476
Регистрация: 15.11.2014
Сообщений: 6,112
Завершенные тесты: 1
28.10.2015, 19:59
Цитата Сообщение от sociodim Посмотреть сообщение
Видимо, тут нужен паттерн "Стратегия", а может и нет, я пока не придумал.
здесь нужен бинд имен команд на функции, которые эти команды реализуют.


например, вот мой консольный робот:

умеет три команды:

C++
1
2
3
void print(){ std::cout << "print()\n"; }
int add(int a, int b){ return a + b; }
int sub(int a, int b){ return a - b; }
соответственно,
умеет печатать текст,
складывать и вычитать значения.

команды и аргументы подаются в видете текста из консольки.

http://rextester.com/NAENGJ62317

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <map>
#include <string>
#include <iostream>
#include <sstream>
#include <functional>
#include <stdexcept>
#include <type_traits>
 
//------------------------------------------------------------------------------------------------------//
 
    template<class Sig, class F>
        struct stream_function_;
 
    template<class R, class... Args, class F>
    struct stream_function_<R(Args...), F>
    {
        stream_function_(F f)
            : _f(f) 
        {}
 
        void operator()(std::istream& args, std::string* out_opt)const
            { call<R>(args, out_opt); }
 
    private:
        template<class T> static T get(std::istream& args)
        {
            T t; 
            if( !(args >> t) )
                args.clear(),
                throw std::invalid_argument("invalid argument to stream_function");
 
            return t;
        }
 
        #define dIS_VOID \
            std::is_same<U, void>::value
        #define dVOID    \
            typename std::enable_if<dIS_VOID, U>::type* = nullptr
        #define dRETURN  \
            typename std::enable_if<!dIS_VOID,U>::type* = nullptr
 
        template<class U, dVOID>
        void call(std::istream& args, std::string*) const
        {
            (void)args;
            _f( std::forward<Args>(get<Args>(args))... );
        }
 
        template<class U, dRETURN>
        void call(std::istream& args, std::string* out_opt) const
        {
            if(!out_opt) 
                return call<void>(args, nullptr);
 
            std::stringstream conv;
            conv << _f( std::forward<Args>(get<Args>(args))... );
            if(!conv)
                throw std::runtime_error("bad return in stream_function");
 
            *out_opt = conv.str();
        }
        #undef dIS_VOID 
        #undef dRETURN
        #undef dVOID
 
        F _f;
    };
 
    template<class Sig, class F>
    stream_function_<Sig, F> 
        stream_function(F f){ return f; }
 
    typedef std::function<void(std::istream&, std::string*)> 
        func_type;
    typedef std::map<std::string, func_type> 
        dict_type;
 
 
//------------------------------------------------------------------------------------------------------//
 
void print(){ std::cout << "print()\n"; }
 
int add(int a, int b){ return a + b; }
int sub(int a, int b){ return a - b; }
 
 
int main()
{
    dict_type func_dict;
    func_dict["print"] = stream_function<void()>(print);
    func_dict["add"]   = stream_function<int(int,int)>(add);
    func_dict["sub"]   = stream_function<int(int,int)>(sub);
 
    std::cout << "[ functions binded ]\n";
    for(const auto& i: func_dict)
        std::cout << " --- " << i.first<<'\n';
 
    std::cout << " enter 'exit' to exit\n";
 
    for(;;)
    {
        std::cout << "Which function should be called?\n";
        std::string tmp;
        std::cin >> tmp;
        
        std::cout << "selected: "<<tmp<<'\n';
 
        if(tmp=="exit")
            break;
 
        const auto it = func_dict.find(tmp);
 
        if(it == func_dict.end()){
            std::cout << "Invalid function '" << tmp << "'\n";
            continue;
        }
 
        try{
            std::string result;
            it->second(std::cin, &result);
            std::cout << "Result: " << (result.empty()? "none" : result) << '\n';
        }
        catch(std::exception const& e){
            std::cout << "Error: '" << e.what() << "'\n";
            std::cin.ignore();
            continue;
        }
        
    }
}
для того, что бы создать поддержку новой команды,
необходимо придумать ей текстовое имя (можно хоть на русском),
и сопоставить этому имени функцию,
которая будет реализовывать эту команду.


то бишь, непосредственно бинд происходит здесь:

C++
1
2
3
4
    dict_type func_dict;
    func_dict["print"] = stream_function<void()>(print);
    func_dict["add"]   = stream_function<int(int,int)>(add);
    func_dict["sub"]   = stream_function<int(int,int)>(sub);
обычный словарик.
ключ - имя команды.
значение - имя функции, с указанием типов аргументов и возвращаемого значения.
0
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru