0

I was writting some class that map specific multidimensionnal array to unidimensionnal array (like 2D array N by M size is like a 1D array NM size you know, and then you can accees the cell [n, m] through [n+mN]). And it was quite boring since I must handle any multidimensional array (forced to copy/paste many times the class definition).

And I found something that could be great in my case: variadic template function. I would like to have my constructor and accessors using variadic template so my accessors can use any number of parameters (2 for 2D array, 3 for 3D array...) and same for my constructor, since I need to save the size in each dimension (N, M, ...) and multiply then to have the size of my unidimentionnal array.

The problem is that I don't know how to do that :( Every examples I found relies on two functions, one with one parameter of type T and another one with one parameter of type T and the Args... args).

Is it possible in one function ? Without recursion or so ? I gave you what I've made so far:

template <typename T, typename... Args>
T returner(T v, Args... args){
    return v;
}

template <typename T>
class Array{

    public:
    int* dim; //contain the size of each dimension
    T* array; //the actual array

    template<typename... Args>
    Array(Args... args){
        constexpr int size = sizeof...(Args);
        dim = new int[size];
        for(int i=0; i<size; i++)
            dim[i] = returner(args...);
            /*dim[0] should be equal to the first argument, dim[1]
            should be equal to the second argument and so on */
    }
};

int main(){
    Array<int>(2,2,2); // meant to be a 3D array, 2cells in each dimension
    return 0:
}

Obviously, "returner" always return the first argument and I understand why, but the only solution I see it to pass the dim array as a parameter and I would like to not do that. Is there a solution ??

PS: I could do that with classical variadic function, like in C, but it would be quite bad in performance :(

2
  • 1
    Could you show us an example where you try to create an Array (what do you pass as Args... typically?)? Because I don't understand what you are trying to do here... Commented Jan 26, 2017 at 13:32
  • I edited my message, hoping it answers your questions. Commented Jan 26, 2017 at 13:35

1 Answer 1

2

This should do what you want (if I understood correctly):

template <typename T>
class Array{

    public:
    int* dim; //contain the size of each dimension
    T* array; //the actual array

    template<typename... Args>
    Array(Args... args){
        constexpr int size = sizeof...(Args);
        dim = new int[size]{args...};
    }
};

But you'd better use std::vector instead of raw pointers - It would save you a lot of troubles:

template <typename T>
class Array{

    public:
    std::vector<int> dim; //contain the size of each dimension
    std::vector<T> array; //the actual array

    template<typename... Args>
    Array(Args... args) : dim{args...} {

    }
};
Sign up to request clarification or add additional context in comments.

10 Comments

Yeaaah :) Thanks, didnt thought i would initialize an array this way actually... thanks ;)
@Viridya You should probably use std::vector here for both dim and array, it would save you a lots of trouble.
@Viridya Is this really what you want? I took your question to mean if you use Array<int>(2,2,2) then the size should be 8, not 3 correct?
@Viridya You can loop, or std::accumulate(std::begin(dim), std::end(dim), 1, std::multiplies<>{}) (assuming you are using std::vector).
@Viridya In some cases it is more generic to use begin(dim) (without std:: actually), so that the code works if dim is a standard container, a raw array (int [4]), or a user defined container with a begin function. In this case, it does not change anything ;) See stackoverflow.com/questions/26290316/….
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.