Можно ли и целесообразно использовать Boost ICL вместо for_each в случае выбора сервиса для запроса? - PullRequest
3 голосов
/ 11 января 2012

У меня есть request структура с std::vector<std::string> arguments.У меня есть std::map<std::string, std::vector<std::string> > services, где ключ - это имя службы, а значение - вектор аргументов, на которые служба отвечает.аргументы разных сервисов могут перекрываться (N сервисы могут иметь одинаковые или частично одинаковые аргументы).Мне нужно найти все услуги, которые соответствуют данному запросу.Интересно, было бы лучше (из удобства кода или чтения и скорость выбора запроса наиболее важно ) для меня использовать Boost ICL вместо текущего for_each, который я использую для выбора услуг (я простоперебрать каждый сервис и посмотреть, представлены ли какие-либо его аргументы в запросе)?

1 Ответ

3 голосов
/ 12 января 2012

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

Если я правильно понял идею, ниже показаны некоторые синтаксические сахара c ++ 11 / boost, которые демонстрируют то, что ясреднее значение с читабельностью:

#include <boost/range/numeric.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/range/adaptors.hpp>

typedef std::vector<std::string> args_t;
typedef std::map<std::string, args_t> service_map;

struct applicable
{
    template <typename T>
        applicable(const T& args) : _args(args) { }

    bool operator()(const service_map::value_type& svc) const
    {
        for (auto& a:_args)
            if (svc.second.end() == boost::find(svc.second, a))
                return false;
        return true;
    }
  private: args_t _args;
};

int main(int argc, const char *argv[])
{
    using namespace boost::adaptors;
    static const service_map services { 
        { "A", { "1","2","3" } }, 
        { "B", { "2","3","4" } },
        { "C", { "3","4","5" } }, 
        { "D", { "4","5","6" } } 
    };

    const std::string label = "request: ";

    for (const auto& req : std::list<args_t> { {"5"}, {"4","3"}, {"1","3"} })
    {
        std::cout << boost::accumulate(req, label) << std::endl;

        for (auto& svc : services | filtered(applicable(req)))
            std::cout << "applicable: " << svc.first << std::endl;
    }
}

Конечно, можно применить много оптимизаций.Но вы знаете, что говорят о преждевременной оптимизации:)

Вывод:

request: 5
applicable: C
applicable: D
request: 43
applicable: B
applicable: C
request: 13
applicable: A
...