Search code examples
c++arraysvariadic-templatesfunctortemplate-meta-programming

How do I convert a template parameter pack into multiple pointer arguments to a function?


I want to implement the following:

template <typename Functor, typename... Params>
void foo(
    size_t n
    /* magic goes here, producing function parameters p1, p2, etc. */
    /* corresponding to the parameter pack.                        */
)
{
    for(size_t i = 0; i < n; i ++) {
        std::cout << Functor()( 
            /* pass p1[i], p2[i], etc. corresponding to the  */
            /* parameter pack.                               */
        )  << '\n';
    }
}

thus foo would expand into something like:

void foo(
    size_t n,
    const int* __restrict__ p1,
    const int* __restrict__ p2
)
{
    for(size_t i = 0; i < n; i ++) {
        std::cout << std::plus()(p1[i], p2[i]) << '\n';
    }
}

I have a vague intuition that I might need to go beyond the standard library into something like Fusion, Brigand or Hana, which I've just started looking into; but - maybe I'm wrong and it's simpler than I think.

Note:

  • A solution in which I pass a tuple of pointers-to-const's is acceptable, although it's sub-optimal - as I can't apply __restrict__ to them (as it is not really C++, I know I know). Actually it's even interesting in itself since I might be able to perform other tricks with the tuple.
  • I don't mind the functor taking a single tuple of pointers instead of multiple individual pointers, either.
  • I'm using nvcc + GCC 5.4.1; the code should be C++11'ish (that is, the part of C++11 that I can compile as CUDA code).
  • I stream the result to std::cout just to not give anybody the idea I'm not doing anything with the functor's return value, and this seemed the most straight-forward thing to do in example code.

Solution

  • template<class Functor, class...Ts>
    void foo( std::size_t n,
      Ts const* __restrict__ ... ts
    ) {
      for(size_t i = 0; i < n; i ++) {
        std::cout << Functor{}( ts[i]...)  << '\n';
      }
    }
    

    well, that was easy.

    Live example.