Разрешено ли двойное / вложенное расширение шаблона вариаций в современном C++?

Я пытался использовать метапрограммирование C++ для создания таких конструкций, как

f(g<0>(args...), g<1>(args...), ... g<n-1>(args...))

даные звания f а также g, целочисленные n и переменные аргументы args...

Однако я решаю проблему, в какой-то момент мне нужно вложенное расширение variadic: одно для args... и одно для 0... n-1, и учитывая ошибки компиляции, которые я получаю, мне интересно, если / когда это возможно в C++11/14/17, и если нет, если есть умный обходной путь?

Ниже и пример того, чего я хотел бы достичь:

struct add
{
    template<int n, class A, class B> static inline auto
    f(const A & a, const B & b) -> decltype(std::get<n>(a)+b)
        { return std::get<n>(a) + b; }
};

template<class... Args> void do_stuff(const Args & ... args)
    { /* do stuff with args */ }

std::tuple<char,short,int,float,double> data = {1,3,5};

map_call<3, add>(do_stuff, data, 1); //< what I'm trying to do
// calls do_stuff(add::f<0>(data,2), add::f<1>(data,1),  add::f<2>(data,1) )
// i.e.  do_stuff(2,4,5)

Где одна из (неудачных попыток) реализаций map_call дается ниже:

// what I tried:
template<class Mapped, class Indicies> struct map_call_help;
template<class Mapped, int... indices>
struct map_call_help<Mapped, std::integer_sequence<int, indices...>>
{
    template<class Callable, class... Args>
    static inline void f(Callable && call, Args && ... args)
    {
        call( Mapped::f<indices>(std::forward<Args>(args)...) ...);
        //                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^      1
        //    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2
        // nested expansion fails with parse error / expected ')'
        // inner expansion is: std::forward<Args>(args)...
        // outer expansion is: Mapped::f<indices>(_forwarded_args_)...
    }
};
template<int n, class Mapped, class Callable, class... Args>
inline void map_call(Callable && call, Args && ... args)
{
    map_call_help<Mapped, std::make_integer_sequence<int, n>>::f(
          std::forward<Callable>(call), std::forward<Args>(args)... );
}

integer_sequence сопутствующие вещи нужны #include <utility> и C++14, или это может быть реализовано в C++11 - см., например, ответы на этот вопрос, если интересно.

1 ответ

Решение

+ Изменить

Mapped::f<indices>

в

Mapped::template f<indices>

Есть также ряд других подобных ошибок, но это была ошибка в этой строке. живой пример

Другие вопросы по тегам