Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create N-element constexpr array in C++11

Hello i'm learning C++11, I'm wondering how to make a constexpr 0 to n array, for example:

n = 5;  int array[] = {0 ... n}; 

so array may be {0, 1, 2, 3, 4, 5}

like image 811
Christopher Aldama Avatar asked Sep 26 '13 04:09

Christopher Aldama


People also ask

What is constexpr in C ++ 11?

The keyword constexpr was introduced in C++11 and improved in C++14. It means constant expression. Like const , it can be applied to variables: A compiler error is raised when any code attempts to modify the value. Unlike const , constexpr can also be applied to functions and class constructors.

Why constexpr instead of define?

#define directives create macro substitution, while constexpr variables are special type of variables. They literally have nothing in common beside the fact that before constexpr (or even const ) variables were available, macros were sometimes used when currently constexpr variable can be used.

What is constexpr static?

static defines the object's lifetime during execution; constexpr specifies that the object should be available during compilation. Compilation and execution are disjoint and discontiguous, both in time and space. So once the program is compiled, constexpr is no longer relevant.

Is constexpr a const?

The principal difference between const and constexpr is the time when their initialization values are known (evaluated). While the values of const variables can be evaluated at both compile time and runtime, constexpr are always evaluated at compile time.


2 Answers

In C++14 it can be easily done with a constexpr constructor and a loop:

#include <iostream>  template<int N> struct A {     constexpr A() : arr() {         for (auto i = 0; i != N; ++i)             arr[i] = i;      }     int arr[N]; };  int main() {     constexpr auto a = A<4>();     for (auto x : a.arr)         std::cout << x << '\n'; } 
like image 163
Abyx Avatar answered Sep 22 '22 22:09

Abyx


Unlike those answers in the comments to your question, you can do this without compiler extensions.

#include <iostream>  template<int N, int... Rest> struct Array_impl {     static constexpr auto& value = Array_impl<N - 1, N, Rest...>::value; };  template<int... Rest> struct Array_impl<0, Rest...> {     static constexpr int value[] = { 0, Rest... }; };  template<int... Rest> constexpr int Array_impl<0, Rest...>::value[];  template<int N> struct Array {     static_assert(N >= 0, "N must be at least 0");      static constexpr auto& value = Array_impl<N>::value;      Array() = delete;     Array(const Array&) = delete;     Array(Array&&) = delete; };  int main() {     std::cout << Array<4>::value[3]; // prints 3 } 
like image 21
Kal Avatar answered Sep 24 '22 22:09

Kal