raggot
raggot

Reputation: 1012

C++ const int not usable in constant expression

I am trying to initialize an array of which I feed the size via an external function.

The external function calculates the size of the vector and outputs them in a pair.

// The function has been simplified for the sake of the question
std::pair< int, int> calculate_size ( 
    const double in1,
    const double in2
)
{
    int temp1   = int(in1/in2);
    int temp2   = int(in2/in1);
    std::pair< int, int> output = make_pair(temp1, temp2);
    return output;
}

Then, somewhere else, I extract the outputs of the above function to generate the sizes of my array using tie (I am compiling using C++11):

// Extract sizes
int tempSize1, tempSize2;
tie(tempSize1, tempSize2) = calculate_size (in1, in2);
const int constSize1 = temp1;  
const int constSize2 = temp2; 

// Initialize vector (compiler error)
std::array<double, constSize1> v1;
std::array<double, constSize2> v2;

The compiler gives the following error: The value of 'constSize1' is not usable in a constant expression.

However, I can't see what I am doing wrong. According to this C++ reference website, the example they bring seems to be exactly what I am doing.

What am I missing? Is there a better way to do this?

Edit:

A comment suggests constexpr is what I need. If I use it without changing the rest, the error message shifts to the constexpr line but remains the same in nature:

// Modified to use constexpr
int temp1, temp2;
tie(temp1,temp2) = calculate_samples (in1, in2);
constexpr int constSize1 = temp1;
constexpr int constSize2 = temp2;

Error: The value of 'temp1' is not usable in a constant expression

Upvotes: 0

Views: 7056

Answers (2)

raggot
raggot

Reputation: 1012

As pointed out in the comments to the original question by nwp and GianPaolo, a possible solution is to avoid using std::array, and use a type of container that allows dynamic memory allocation instead, like std::vector.

Upvotes: 0

AVH
AVH

Reputation: 11506

If you need array (as opposed to vector), then marking the function as constexpr works perfectly fine.

For working code, see below. Here's the code running on Coliru: http://coliru.stacked-crooked.com/a/135a906acdb01e08.

#include <iostream>
#include <utility>
#include <array>

constexpr std::pair<int, int> calculate_size (
    const double in1, const double in2) {
  return std::make_pair(
    static_cast<int>(in1 / in2),
    static_cast<int>(in2 / in1));
}

int main() {
  constexpr auto sizes = calculate_size(4, 2); 

  std::array<double, sizes.first> v1;
  std::array<double, sizes.second> v2;

  std::cout << "[Size] v1: " << v1.size() << " - v2: " << v2.size() << "\n";
}

Which prints: [Size] v1: 2 - v2: 0.

Upvotes: 3

Related Questions