Функтор вызова из шаблона variadic

0

Можно ли написать вариационный шаблонный класс

template<typename Functor, int... D>
struct Foo
{
    void bar()
    {
        // ???
    }
};

Это эквивалентно

template<typename Functor, int D0>
struct Foo<Functor, D0>
{
    void bar()
    {
        Functor f;
        double d0[D0];
        f(d0);
    }
};

template<typename Functor, int D0, int D1>
struct Foo<Functor, D0, D1>
{
    void bar()
    {
        Functor f;
        double d0[D0];
        double d1[D1];
        f(d0, d1);
    }
};

// And so on...

То есть количество аргументов, передаваемых функтору, равно числу аргументов шаблона. Аргументы должны быть выделены в стеке.

Теги:
c++11
variadic-templates

3 ответа

5
Лучший ответ

После версии с аргументами в стеке через std::tuple:

// Helper class to be able to use expansion of std::get<Index>(tuple)
template <int... Is> struct index_sequence {};

// Following create index_sequence<0, 1, 2, .., sizeof...(Is) - 1>
template <int Index, int... Is>
struct make_index_sequence { // recursively build a sequence of indices
    typedef typename make_index_sequence<Index - 1, Index -1, Is...>::type type;
};

template <int... Is>
struct make_index_sequence<0, Is...> { // stop the recursion when 0 is reached
    typedef index_sequence<Is...> type;
};

template<typename Functor, int... Ds>
struct Foo
{
    void bar()
    {
        bar(typename make_index_sequence<sizeof...(Ds)>::type());
    }
private:
    template <int... Is>
    void bar(index_sequence<Is...>)
    {
        Functor f;
        std::tuple<double[Ds]...> t; // std::tuple<doudle[D0], double[D1], ..>
        f(std::get<Is>(t)...);       // f(std::get<0>(t), std::get<1>(t), ..);
    }
};
  • 0
    действительно хорошая реализация.
  • 0
    техника, которую вы использовали, определяет типы и использует число типов, определяемых как Indices в get<> верно? не могли бы вы объяснить это немного? мне трудно оборачиваться вокруг расширения indices . было бы здорово, если бы вы могли опубликовать правку с объяснением. большое спасибо :-)
Показать ещё 3 комментария
2

Это то, что вы хотите?

template<typename Functor, int... D>
struct Foo
{
    template<std::size_t N>
    std::array<double, N> create()
    {
       return std::array<double, N>();
    }

    void bar()
    {
       Functor f;
       f(create<D>()...);
    }
};
  • 0
    Чистое и простое решение ИМХО. но ОП попросил немного другое, кроме распаковки в функтор, ему также нужна локальная копия каждого массива.
0

Возможно, это работает:

template <typename Functor, int i, int... others>
struct Foo
{
  template <typename ...T>
  void bar(T ... rest)
  {
    double d[i];
    Foo<Functor, others...> foo;
    foo.bar(rest..., d);
  }
};

template <typename Functor, int i>
struct Foo<Functor, i>
{
  template <typename ...T>
  void bar(T ... rest)
  {
    double d[i];
    Functor f;
    f(d, rest...);
  }
};
  • 0
    @ Jarod42 Да, может быть. Но вы можете прокомментировать, почему нет, пожалуйста?
  • 0
    Я неправильно понял ваше решение ... Как примечание, ваша подпись в bar отличается от OP. Вы можете назвать это с посторонним параметром.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню