2

I'm currently learning about template meta-programming in c++ and stumbled across variable templates. As a fun exercise, I decided to implement compile time static array with following usage -

my_array<1,2,3,4> arr; // gives an array with 4 members = 1,2,3,4 

I've tried several iterations of my attempt, removing syntax errors along the way but now I'm stuck since no compiler gives useful warning. Here's my current code -

#include <iostream> template<size_t... Enteries> constexpr size_t my_array[sizeof...(Enteries)] = {Enteries...}; int main() { my_array<1,2,3,4,5,6> arr; } 

but currently it gives following error with clang -

static_array.cpp:7:10: error: expected ';' after expression my_array<1,2,3,4,5,6> arr; ^ ; static_array.cpp:7:24: error: use of undeclared identifier 'arr' my_array<1,2,3,4,5,6> arr; ^ static_array.cpp:7:2: warning: expression result unused [-Wunused-value] my_array<1,2,3,4,5,6> arr; ^~~~~~~~~~~~~~~~~~~~~ 1 warning and 2 errors generated. 

and with gcc -

static_array.cpp: In function ‘int main()’: static_array.cpp:7:24: error: expected ‘;’ before ‘arr’ my_array<1,2,3,4,5,6> arr; ^~~ static_array.cpp:7:27: warning: statement has no effect [-Wunused-value] my_array<1,2,3,4,5,6> arr; 

How should I proceed forward to implement this thing(preferably with variable templates since I know this can be implemented with old struct technique).

1
  • 4
    my_array<1,2,3,4,5,6> is the array. Commented Jun 23, 2017 at 4:42

3 Answers 3

5

As mentioned in the comments to the question, my_array<1,2,3,4,5,6> isn't a type. my_array is a variable template, it has a type you can use once specialized but it is not a type, you cannot use it the way you are doing.
You cannot declare variables having type my_array<1,2,3,4>, but you can use the variable my_array<1,2,3,4>. As an example, do you want to get the N-th element? my_array<1,2,3,4,5,6>[N];.

Sample program:

#include <iostream> template<size_t... Enteries> constexpr size_t my_array[sizeof...(Enteries)] = {Enteries...}; int main() { std::cout << my_array<1,2,3,4,5,6>[0] << std::endl; } 

Output:

1 
Sign up to request clarification or add additional context in comments.

Comments

2

Did you mean to make a type?

#include <stdexcept> template < size_t... Enteries > class my_array { constexpr static size_t const N = sizeof...(Enteries); constexpr static size_t const value[N] = {Enteries...}; public: constexpr size_t operator[](size_t idx) const { if ( idx < N ) return value[idx]; else throw std::out_of_range("my_array index out of range");; } }; int main() { my_array<1,2,3,4,5,6> arr; static_assert( arr[0] == 1, "!" ); static_assert( arr[1] != 5, "!!" ); //static_assert( arr[9] == 0, "!!!" ); // Does not compile } 

Comments

1

There are a few approaches to compile-time arrays

With constexpr

Just qualify an array with constexpr

constexpr size_t arr[] = {3, 2, 1}; 

With variable templates

template<size_t... E> constexpr size_t arr[] = {E...}; 

This is known as a variable template, arr is the variable, therefore you would use it like one

for(auto i : arr<42, 420, 4200>) std::cout << i << std::endl; 

Live

With non-type template parameters

This functionality is provided in C++14 already, namely std::integer_sequence. This is not as straightforward as a simple array and is used mostly when you need a parameter pack of numbers

template<typename T, T... I> void print(std::integer_sequence<T, I...>) { (std::cout << ... << I); // fold expression from C++1z, parentheses required } print(std::integer_sequence<size_t, 1, 2, 3>{}); 

Live

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.