Pedro Lobo
Pedro Lobo

Reputation: 27

How to turn a variable content constant for use it as the size of std::array?

I have a size variable that belongs to the class. I would like to use it as the size of a std::array, but I was not able to do this. I found some articles that mention constexpr, but nothing useful so far. Can you help me?

#include<array>
#include<iostream>

class MyClass{
private:
        int size; //variable I need to copy the content and make it constant.
        void calculateSize(int x){
                size = 2 * x;
        }

public:
        MyClass(){}

        void createArray(int val){

                calculateSize(val);
                std::cout << "the size is: " << size << std::endl;
                std::array<int, size> myArray; // error
        }
};

int main(){

        MyClass c;
        c.createArray(5);
        return 0;
}

The error:

main.cpp: In member function ‘void MyClass::createArray(int)’: main.cpp:20:19: error: use of ‘this’ in a constant expression std::array myArray;

Upvotes: 1

Views: 202

Answers (3)

SacrificerXY
SacrificerXY

Reputation: 334

As an alternative solution, using templates:

template <int _size>
class MyClass{
private:
    // size calculation at compile time
    constexpr static int size = _size * 2; 

public:
    // parameter removed since it's unnecessary
    void createArray(){  
        std::cout << "the size is: " << size << std::endl;
        std::array<int, size> myArray;
    }
};

int main(){
    // pass size as template argument
    MyClass<5> c;
    c.createArray();
    return 0;
}

Upvotes: 2

Jordan
Jordan

Reputation: 417

The problem here is a misunderstanding of what constant means. In C++, std::array's must be of constant size, where constant means "the size is known at compile-time." As your class suggests, the size variable is calculated at runtime. Likewise, the constexpr keyword can only be used for a variable whose value is known at compile time and will not ever change.

So you have a couple options.

  1. You can use a std::vector and initialize it with a size

    std::vector<int> vec(5); // Initializes a vector of size 5
    
  2. If you really do know the size of the array at compile time, you can use constexpr

    constexpr int size = 2 * 10;
    std::array<int, size> arr; // Make an array of size 20
    

Upvotes: 4

eerorika
eerorika

Reputation: 238421

This is simply not possible. Non-static member variables are not compile time constant values. Template arguments must be compile time constants. Therefore you cannot use a non-static member variable as a size of a std::array.

If you want to have an array with a size determined at runtime, then you need to allocate the array dynamically. The simplest way to achieve that is to use a std::vector.

If you want to have a constant sized array, then you can use a compile time constant for that purpose. Such value cannot be a non-static member variable.

Upvotes: 2

Related Questions