Set array size at compile time thru constructor

Hello,

How do I set the size of a member array via the class constructor if I know the size at compile time. I can do this with templates, see below, but this leads to code bloats, I think.

So one class declaration but objects with different array sizes.

Can't use constexpr.
Can't use STL.
Can't use new.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>

using namespace std;

template<int T>
class MyArray
{
    private:
        int array[T];
    public:
        int getSize()
        {
            return sizeof(array)/sizeof(int);
        }
};

//class MyArray
//{
//    private:
//        int array[];
//    public:
//        MyArray(int i):array[???]{};
//        int getSize()
//        {
//            return sizeof(array)/sizeof(int);
//        }
//};

int main()
{
    MyArray<6> myArray1;//myArray1(6)
    cout<<myArray1.getSize()<<endl;
    MyArray<9> myArray2;//myArray2(9)
    cout<<myArray2.getSize()<<endl;
    return 0;
}
It doesn't lead to code bloat. It's a proper use of templates.
std::array is implemented the same way: http://www.cplusplus.com/reference/array/array/
I must be misunderstanding. Can't you use a normal array?

 
int array[5]; // <- 5 is known at compile time 
Hi there,

Constructors are called when objects are created. Objects are created when the program runs, not at compile time. Why do you feel MyArray<6> myArray1; is more bloated than MyArray myArray1(6);?

Most of the STL is built on templates, so this becomes quite natural over time. The only reason I could see is that you are not used to the notation yet, but templates are just an important component of the language that it's worth familiarizing yourself with them.

Hope that helps, please do let us know if you have any further questions.

All the best,
NwN
With templates, doesn't it generate separate class definitions? So the function code, getSize() in this case, is repeated each time a new template class is declared.

Also, I might want to do more arraying:
MyArray myArrayz[] = {MyArray(6), MyArray(9)};
Hi there,

The compiler creates a new definition only when you create an instance of a template using type-parameters, not value-parameters. For instance:

1
2
3
4
5
6
7
8
template<typename T> //type parameter
struct array
{
    T container[10];
}

array<int> int_array; //creates definition for array<int>
array<double> double_array; //creates a definition for array<double> 


All you are passing to the template is a value which is always of type int, so the compiler has no reason to create a new definition. You may actually require to use this if you need multidimensional arrays. Have a look at the STL implementation documentation: http://www.cplusplus.com/reference/array/array/

All the best,
NwN
Last edited on
MyArray<6> myArray1;

creates

1
2
3
4
5
6
7
8
9
10
class MyArray6
{
    private:
        int array[6];
    public:
        int getSize()
        {
            return sizeof(array)/sizeof(int);
        }
}myArray1;


MyArray<9> myArray2;

creates

1
2
3
4
5
6
7
8
9
10
class MyArray9
{
    private:
        int array[9];
    public:
        int getSize()
        {
            return sizeof(array)/sizeof(int);
        }
}myArray2;


No? I can't umbrella myArray1 and myArray2 under one definition, with which I want to declare an array as MyArray myArrayz[] = {MyArray(6), MyArray(9)};
Last edited on
No? I can't umbrella myArray1 and myArray2 under one definition, with which I want to declare an array as


No... because MyArray<6> and MyArray<9> are different types. You could do that with polymorphism, but it would be a little silly.... it'd be better to just dynamically allocate the array.

Can't use constexpr.
Can't use STL.
Can't use new.


I'm compelled to ask why.
The compiler does not support those features for the selected target.
You have a C++ compiler that won't support new ?!?

That's... unusual.
Last edited on
Maybe it does support it, at all events no dynamic allocations allowed.
My brain keeps coming back to normal arrays:

int foo[10];

Without dynamic allocation, I cannot think of a good way to treat all the arrays as the same type. The only way I can think of would be to make them all the same size. That is... make them all large enough for the largest array needed... and have those which do not need that extra space simply not use it. This is not memory efficient, but it's the only way I can think of to accomplish a uniform interface.


The only other thing I can think of is to employ some form of polymorphism (but this is difficult without dynamic allocation).
┬┐does `placement new' count as dynamic memory?
kernulz wrote:
With templates, doesn't it generate separate class definitions? So the function code, getSize() in this case, is repeated each time a new template class is declared.

not quite: it generates types, and no, code is not generated for member functions of templates just because the template was declared, specialized, or instantiated: you need to actually be compiling source code that makes a call to the function (or, to be formal, ODR-uses it). And then, since it's a template, it will just get inlined, so cout << myArray2.getSize() will be compiled as cout << 9
> And then, since it's a template, it will just get inlined
┬┐?
I should have said, since it's a template function whose result depends on compile-time values only.
Topic archived. No new replies allowed.