【问题标题】:variable templates compile time array变量模板编译时间数组
【发布时间】:2017-06-23 04:33:13
【问题描述】:

我目前正在学习 c++ 中的模板元编程,并偶然发现了变量模板。作为一个有趣的练习,我决定使用以下用法实现编译时静态数组 -

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

我已经尝试了几次迭代,一路上消除了语法错误,但现在我被卡住了,因为没有编译器给出有用的警告。这是我当前的代码 -

#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;
}

但目前它在 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.

和 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;

我应该如何继续实现这个东西(最好使用变量模板,因为我知道这可以用旧的结构技术来实现)。

【问题讨论】:

  • my_array&lt;1,2,3,4,5,6&gt; 是数组。

标签: c++ templates c++14 variadic-templates template-meta-programming


【解决方案1】:

正如问题的 cmets 中所述,my_array&lt;1,2,3,4,5,6&gt; 不是类型。 my_array 是一个变量模板,它有一个你可以使用一次专门化的类型,但它不是一个类型,你不能按照你的方式使用它。
您不能声明类型为my_array&lt;1,2,3,4&gt; 的变量,但可以使用变量my_array&lt;1,2,3,4&gt;。 举个例子,你想得到第 N 个元素吗? my_array&lt;1,2,3,4,5,6&gt;[N];.

示例程序:

#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;
}

输出:

1

【讨论】:

    【解决方案2】:

    你的意思是创建一个类型吗?

    #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
    }
    

    【讨论】:

      【解决方案3】:

      编译时数组有几种方法

      constexpr

      只需使用constexpr 限定一个数组

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

      带有变量模板

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

      这被称为variable templatearr 是变量,因此您可以像使用它一样使用它

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

      Live

      带非类型模板参数

      此功能已在 C++14 中提供,即std::integer_sequence。这不像简单的数组那么简单,主要在需要数字参数包时使用

      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

      【讨论】:

        猜你喜欢
        • 2015-12-21
        • 1970-01-01
        • 2022-01-19
        • 2015-09-15
        • 2021-05-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多