2

I'm making an N dimensional image format, I want to store the raw data in an

std::array<T, multiple of all dimensions>* where T is the type of single channel pixel value

I want the constructor to take an array of channels like {20, 30, 50} to make a 20x30x50 bitmap for example which would make the total length of data 30000. In the end, I want to be able to declare the channel like this

auto* channelRed = new Channel<uint32_t>({20, 30, 50});

problem is that std::array expects size to be passed in the template parameters and that would throw a wrench in my N dimensional plan.

How can I set up a std::array pointer as a class field in my class so that I could define the length of the array during the constructor execution?

PS! yeah, I know I can easily just use a regular array which is what I'm doing right now. I'm just trying to figure out what std::array is good for.

user81993
  • 6,167
  • 6
  • 32
  • 64
  • 1
    It sounds like you need `std::vector`, not `std::array`. – juanchopanza Aug 22 '15 at 00:17
  • `std::array` is especially and only useful if you know the array size in advance. So either make your class a class template (using the array’s size as its argument), or use `std::vector`. – Robin Krahl Aug 22 '15 at 00:18

2 Answers2

8

You can't. A std::array must know its size at compile-time. It's part of the type! A std::array<int, 2> and a std::array<int, 3> aren't just different sizes, they're completely different types.

What you need is a dynamically sized array instead of a statically sized one. Namely: std::vector<uint32_t>:

template <typename T>
class Channel {
    std::vector<T> v;

public:
    Channel(std::initializer_list<T> dims)
    : v(std::accumulate(dims.begin(), dims.end(), size_t{1}, 
                        std::multiplies<size_t>{}))
    { }
};
Barry
  • 286,269
  • 29
  • 621
  • 977
-1

If you know the # of parameters at compile time and want to build your Channel based on that, it's possible to do that with an array (and a helper function).

You can define your class like so:

template <typename Array>
class Channel {
    Array a;

public:
    Channel(Array arr)
    : a(arr)
    { }
};

Then have a helper function take care of the type nastyness (based on this make_array):

template<class T, class... Tail>
auto make_channel(T head, Tail... tail) -> Channel<std::array<T, 1 + sizeof...(Tail)>>
{
     return Channel<std::array<T, 1 + sizeof...(Tail)>>({ head, tail ... });
}

Then in your program you can simply do something like:

auto channelRed = make_channel<uint32_t>(20, 30, 50);

And you'll get a Channel, with an array containing {20, 30, 50}.

Community
  • 1
  • 1
Red Alert
  • 3,786
  • 2
  • 17
  • 24