1

I've been trying to use C++ metaprogramming to build constructs such as

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

given callables f and g, integer n and variadic arguments args...

However I turn the problem, at some point, I need a nested variadic expansion : one for args... and one for 0 ... n-1, and given the compilation errors I'm getting, I'm wondering if/when it's possible in C++11/14/17, and if not, if there is a clever work-around ?

Below, and example of what I'd like to achieve:

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)

Where one of the (failed try) implementations of map_call is given below:

// 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 related stuff needs #include <utility> and C++14, or it can be implemented in C++11 -- see e.g. answers to this question if interested.

Community
  • 1
  • 1
Antoine
  • 13,494
  • 6
  • 40
  • 52
  • 1
    [live example](http://coliru.stacked-crooked.com/a/72d02eafd950c243) of your above code generates an error at a completely different spot, even after I fixed the `templace` typo. Please post the actual code that is generating your error, after reducing it and confirming that the error is still generated. – Yakk - Adam Nevraumont Apr 16 '15 at 14:02
  • @Yakk: thanks for your review. As I said, `integer_sequence` related code is not included to avoid lengthy post. If you want I can reduce it and include it here to have a complete code. – Antoine Apr 16 '15 at 14:06
  • The problem is, when I went through your code and removed the simple syntax errors and replaced `std::integer_sequence` with `std::index_sequence`, *there was nothing left to do*. You misspelled `template`, you missed a `template`, your use of `make_int_seq` was a bit quirky, you cannot pass a template function as a single object, yada yada -- all could easily be caused by your "simplification" without reproduction. Post a [MCVE](http://stackoverflow.com/help/mcve). For example, `do_stuff` is not an object, it is a template function. You cannot pass it as an argument to a function. – Yakk - Adam Nevraumont Apr 16 '15 at 14:12
  • Thanks, I fixed my code (to keep it small, it now needs C++14), but still have the same issue, [see live example](http://ideone.com/QRLTzF), so I'm very interested in your *nothing left to do* ;) – Antoine Apr 16 '15 at 14:16
  • You're right : I got confused by the compile-error message and was looking in the wrong direction. The answer to the question is : nested variadic expansion is possible (I wasn't sure), but there is another problem in the code I posted ;) – Antoine Apr 16 '15 at 14:21

1 Answers1

1

Change

Mapped::f<indices>

to

Mapped::template f<indices>

There are a number of other similar errors as well, but that was the error on that line. live example

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
  • Thanks a lot, guess I misinterpreted the compiler error here. Indeed, this was also the issue in the actual code I'm working on. – Antoine Apr 16 '15 at 14:19