На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
  
> Возможно ли определить порядковый номер аргумента при развертке variadic.
    Понадобилось узнать порядковый нормер типа в вариадике при вызове:
    ExpandedWrap disabled
      caller(get<typename std::decay<Args>::type>(what)...);

    caller - функциональный объект
    Args - его аргументы (variadic)
    get - функция получения значения аргумента из what, по совместительству выполняет конвертацию элемента к нужному типу
    what - по сути массив с аргументами (а вообще контейнер с перегруженными [])

    Пришли идеи:
    1. Сделать список типов из вариадика и искать нужный тип в нём, не подходит, т.к. типы могут повторяться
    2. Сделать какую-нить обёртку и при обвявлении caller использовать, не подходит из-за корявости
    3. Считать внутри, но порядок вызовов get для аргументов неопределен
    Варианты иссякли

    Возможно ли узнать порядковый номер аргумента вариадика, для которого производится вызов get?
    Сообщение отредактировано: Axis -
      Что-то я даже не могу себе представить код, которому не то, что бы это пригодилось, хотя бы синтаксис использования им сего номера не представляется. Можешь набросать что-либо экзампловое?

      P.S. Навскидку если: собрать из Args некий std::tuple.
        Вообще хочется что-то типа этого реализовать
        ExpandedWrap disabled
          void worker1(const std::string& a, int b) { ... }
          void worker2(int a) { ... }
           
          dispatcher d;
          d.add("/(\\w+)/(\\d+)", worker1);
          d.add("/(\\d+)", worker2);
          d.dispatch("/action/123");
          d.dispatch("/14231");


        В итоге по регулярке разбираю, через lexical_cast привожу к нужному типу, в итоге возвращается массив захватов, его и хотелось прокинуть с использованием вариадиков, а не кучей классов под нужное кол-во аргументов. Внутрях используется для хранения обработчика type erasure.
          Цитата Axis @
          В итоге по регулярке разбираю, через lexical_cast привожу к нужному типу, в итоге возвращается массив захватов, его и хотелось прокинуть с использованием вариадиков

          Не очень понимаю как вы хотите это осуществить. Дело в том, что variadic - сущность времени компиляции, а парсинг regexp'а и соответствующие им действия - run-time.

          Короче, не понятно для чего нужен порядковый номер...
            Не, ну если этот dispatcher::add() сделать как-нибудь constexpr...
            Теперь не понятно, как связать эти два поста, Axis. Ладно, подойдём с другой стороны.
            ExpandedWrap disabled
              template <typename ...Args>
              void called(Args ...args)
              {
                std::tuple<Args...> t(args...);
               
                /* ... */
              }
            Что не так с этим кодом?
              Цитата Qraizer @
              ну если этот dispatcher::add() сделать как-нибудь constexpr...

              не только add, но и dispatch. И разбор регэкспов в компил тайм. Ну то есть теоретически это возможно, но практически...

              Цитата Axis @
              Понадобилось узнать порядковый нормер типа в вариадике при вызове:

              http://stackoverflow.com/questions/1501409...plate-expansion
                Я недавно делал обертку над C API яваскрипт-движка WebKit. Я реализовал возможность регистрации произвольной std::function в качестве js-функции, которую можно вызывать из js-кода. Для этого нужно было вектор js-значений преобразовать в типизированные аргументы std::function. Где-то на Stack Overflow нашел вот такой код (проверял в VS 2013)

                ExpandedWrap disabled
                  // call function with arguments expanded from std::tuples
                  template<typename Result, typename... Args, typename Tuple, std::size_t ... Indices>
                  Result callFunctionWithTupleImpl(std::function<Result (Args...)>& f, Tuple&& t, std::index_sequence<Indices...>) {
                      return f(std::get<Indices>(std::forward<Tuple>(t))...);
                  }
                  template<typename Result, typename... Args, typename Tuple>
                  Result callFunctionWithTuple(std::function<Result (Args...)>& f, Tuple&& t) {
                      using IndexSequence = std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>::value>;
                      return callFunctionWithTupleImpl(f, std::forward<Tuple>(t), IndexSequence());
                  }


                Здесь испольуется std::index_sequence, которого пока нет в стандарте, но обещают добавить в С++ 14. Реализацию взял из WebKit.

                ExpandedWrap disabled
                  // Implementation of std::index_sequence from WebKit (Source/WTF/wtf/StdLibExtras.h)
                   
                  namespace std {
                   
                  // Compile-time integer sequences
                  // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3658.html
                  // (Note that we only implement index_sequence, and not the more generic integer_sequence).
                  template<size_t... indexes> struct index_sequence {
                      static size_t size() { return sizeof...(indexes); }
                  };
                   
                  template<size_t currentIndex, size_t...indexes> struct make_index_sequence_helper;
                   
                  template<size_t...indexes> struct make_index_sequence_helper<0, indexes...> {
                      typedef std::index_sequence<indexes...> type;
                  };
                   
                  template<size_t currentIndex, size_t...indexes> struct make_index_sequence_helper {
                      typedef typename make_index_sequence_helper<currentIndex - 1, currentIndex - 1, indexes...>::type type;
                  };
                   
                  template<size_t length> struct make_index_sequence : public make_index_sequence_helper<length>::type { };
                   
                  } // namespace std
                  Цитата alexeibs @
                  Я недавно делал обертку над C API яваскрипт-движка WebKit.

                  Что-то подобное и нужно, спс. Подобное еще надо для обёртки над шаблонизатором ClearSilver, задача точно такаяже, только для функций самого шаблонизатора вызываемых из шаблонов. Посмотрю, попробую разобраться.
                    Посмотри еще здесь может что пригодится
                    http://habrahabr.ru/post/183830/
                      Принцип понял, получилось, завелось, адаптировал для своего решения, ибо тупл мне не подходит.
                      0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                      0 пользователей:


                      Рейтинг@Mail.ru
                      [ Script execution time: 0,0378 ]   [ 16 queries used ]   [ Generated: 19.04.24, 13:26 GMT ]