0

I couldn't really find a solution online anywhere for this. I am a bit of a dinosaur from before C++11 and I couldn't figure out typecasting a constexpr.

Does anyone know how to convert a C-style array and/or a std::vector (integer) element into a constexpr?

That is to say, let's say

int a[]={1,2};
vector<int> v={1,2};

how would I convert a[1] and v[1] into constexpr?

constexpr int b=a[1];

for example, a compiler would complain in a for loop.

error: the value of ‘a’ is not usable in a constant expression
     constexpr int b=a[i];

I am pretty much out of ideas for the time being. Thanks

12
  • 2
    You can't. Only constant expressions can be assigned to a constexpr variable. Commented Aug 19, 2020 at 14:02
  • 2
    you'd need a timemachine to turn a value that is only known at runtime into one that is already known at compile-time Commented Aug 19, 2020 at 14:05
  • You can't , please look in cppreference (en.cppreference.com/w/cpp/language/constexpr ) "A constexpr variable must satisfy the following requirements: its type must be a LiteralType. it must be immediately initialized the full-expression of its initialization, including all implicit conversions, constructors calls, etc, must be a constant expression " Commented Aug 19, 2020 at 14:18
  • AdabH, I just did. Wow.. things have changed a lot since 2017... Commented Aug 19, 2020 at 14:34
  • Can you please tell us what problem you are trying to solve by converting a dynamic value to constexpr? Commented Aug 19, 2020 at 14:34

2 Answers 2

3

Suggestion: if you can use at least C++14, instead of std::vector, if you can, use a std::array

Declaring it constexpr

#include <array>

int main () 
 {
   constexpr std::array<int, 2u> a {1, 2};

   constexpr auto b = a[1];
 }

std::array is a type compatible with constexpr and so it's operator[]() (const version), or also it's at() method (const version).

C++14 is required because in C++11 std::array::operator[]() const and std::array::at() const aren't constexpr methods so can't be used in a constant expression.

Unfortunately, std::vector require memory allocation so isn't compatible (before C++20) with constexpr.

For the C-style array case, you have only to declare it constexpr

int main () 
 {
// VVVVVVVVV   
   constexpr int a[] = {1,2};

   constexpr auto b = a[1];
 }
Sign up to request clarification or add additional context in comments.

5 Comments

@idclev463035818 - Why not? Done.
Okay, that looks quite promising. Is there a way to generalize to a[i], or does the index have to be well defined?
@SjL - Obviously the index has to be a constant expression too; so constexpr auto index = 0u; constexpr auto b = a[index]; works, auto index = 0u; constexpr auto b = a[index]; doesn't.
I see, do you have a suggestion on how to approach this if I want iterate this in a for loop?
@SjL - If you just know the use of variadic templates... I usually pass through an helper function that accept a std::index_sequence (that contain indexes as template values, so a sequence of constant expressions) and calling it using std::make_index_sequence (that generate the template sequence of indexes).
0

The constexpr must have a constant expression, i.e. they must be known at compile time. You can't perform an assignment to b with a, it's an error in this case.

In the given code snippet, the a isn't defined as constexpr, thus, it doesn't explicitly tells the compiler that the expression is a constant.

1 Comment

But a is "known at compile time", or rather we know what it holds, at compile time. Please explain to OP why this is not enough.

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.