0

I want to write a function that take n int as a coordinate of array with the max value for each coordinate. This function linearizes these parameters to target a specific index.

int my_func(int x, int y, int XMAX, int YMAX){
    return x + y*XMAX;
}

Here is a 2D example, but I can make something generic thanks to variadic template quite easily. However, I am stucked when I want to make the same function that does not take the max value for each coordinate in parameters. Something like that :

template<int XMAX, int YMAX>
int my_func(int x, int y){
    return x + y*XMAX;
}

Here it works in 2D, but I want to generalize that from 1 to N dimensions and I don't know how I could achieve that. I was thinking to pass an int N which is the number of dimension and an std::array<N, int>::iterator which is an iterator on the std::array containing the actual max value, but it does not compile. Here is the code:

template <int N, std::array<size_t, N>::iterator it>
void foo(){...}

It says ’std::array<long unsigned int, N>::iterator’ is not a type. If i just pass the std::array, I get the following error : ’struct std::array<long unsigned int, N>’ is not a valid type for a template non-type parameter

Does someone have an idea on how to solve such a problem ? I am using C++ 11 (G++ 5.4.0).

Viridya
  • 640
  • 5
  • 13
  • 1
    use [pack](http://en.cppreference.com/w/cpp/language/parameter_pack) of [non-type template parameters](http://stackoverflow.com/documentation/c%2b%2b/460/templates/16713/non-type-template-parameter#t=201704191346386294095) – W.F. Apr 19 '17 at 13:45
  • @W.F. I don't see how it can help me here. – Viridya Apr 19 '17 at 15:06
  • C++14's [std::integer_sequence](http://en.cppreference.com/w/cpp/utility/integer_sequence) (easily writable in C++11). – O'Neil Apr 19 '17 at 15:13

1 Answers1

1

First of all, I suppose you did a little mistake in your function, because if you need to linearize the accessing of array you need to multuply y by XMAX

int my_func(int x, int y, int XMAX, int YMAX){
    return x + y*XMAX;
}

because each row is composed of XMAX items. For answer to your question I used a template parameter pack

template <int N>
int my_func(int x)
{
    assert(x < N);
    return x;
}

template <int N, int... Ns, typename ARG, typename... ARGS>
ARG my_func (ARG x, ARGS... args)
{
    assert(x < N);
    return x + N*my_func<Ns...>(args...);
}



int main()
{
    int a = 1;
    int b = 2;
    int c = my_func<10, 3>(a, b);
}

The fist function is the base for the recursion, the second function use two parameter packs but also 2 explicit template parameter to make the recursion possible.

alangab
  • 849
  • 5
  • 20
  • First, I have modified my post, indeed it was a mistake. Anyway, that is smart !!! I did thought i could pass pack like that, thanks a lot ! I was surrendering, using functor instead :) Thanks a lot ! – Viridya Apr 20 '17 at 08:29