简体   繁体   English

变量模板编译时间数组

[英]variable templates compile time array

I'm currently learning about template meta-programming in c++ and stumbled across variable templates. 我目前正在学习c ++中的模板元编程,并偶然发现变量模板。 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 - 但目前它与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 - 和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). 我应该如何继续实现这个东西(最好用变量模板,因为我知道这可以用旧的struct技术实现)。

As mentioned in the comments to the question, my_array<1,2,3,4,5,6> isn't a type. 正如对问题的评论中所提到的, my_array<1,2,3,4,5,6>不是一种类型。 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. my_array是一个变量模板,它有一个你可以使用的类型,但它不是一个类型,你不能按照你的方式使用它。
You cannot declare variables having type my_array<1,2,3,4> , but you can use the variable my_array<1,2,3,4> . 您不能声明类型为my_array<1,2,3,4>的变量,但可以使用变量my_array<1,2,3,4> As an example, do you want to get the N-th element? 举个例子,你想获得第N个元素吗? 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

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
}

There are a few approaches to compile-time arrays 编译时数组有几种方法

With constexpr 随着constexpr

Just qualify an array with constexpr 只需用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 这被称为变量模板arr 是变量 ,因此您可以像使用它一样使用它

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 . 此功能已在C ++ 14中提供,即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 生活

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM