【问题标题】:Array Initialisation Compile Time - Constexpr Sequence数组初始化编译时间 - Consexpr 序列
【发布时间】:2018-02-06 23:30:56
【问题描述】:

我正在阅读关于 SO 的this 问题。

这个问题本身并没有那么有趣,但我想知道它是否存在以及如何实现编译时解决方案。

关于第一个序列:

除了可以被3整除的所有数字。

顺序应该是这样的:

[1, 2, 4, 5, 7, 8, 10, 11, 13, 14, ...]

通过归纳,我找到了该序列的数学公式:

 f(0) = 0;
 f(x > 0) = floor[(3x - 1) / 2];

所以我实现了一个 C++ constexpr 函数,它在序列中生成 i-th 数字:

#include <type_traits>

template <typename T = std::size_t>
constexpr T generate_ith_number(const std::size_t index) {
  static_assert(std::is_integral<T>::value, "T must to be an integral type");

  if (index == 0) return 0;
  return (3 * index - 1) / 2;
}

现在我想生成一个“编译时数组/序列”,它存储序列的前 N ​​个数字。

结构应该是这样的:

template <typename T, T... values>
struct sequence {};

template <typename T, std::size_t SIZE>
struct generate_sequence {};  // TODO: implement

问题(不止一个,但相互关联):

1) 如何实现那种integer_sequence

2) 是否可以在编译时从 integer_sequence 构建 std::array

【问题讨论】:

    标签: c++ arrays c++11 constexpr compile-time


    【解决方案1】:

    1) 如何实现那种integer_sequence

    template <std::size_t... Is> 
    constexpr auto make_sequence_impl(std::index_sequence<Is...>)
    {
        return std::index_sequence<generate_ith_number(Is)...>{};
    }
    
    template <std::size_t N> 
    constexpr auto make_sequence()
    {
        return make_sequence_impl(std::make_index_sequence<N>{});
    }
    

    2) 是否可以在编译时从 integer_sequence 构建 std::array

    template <std::size_t... Is>
    constexpr auto make_array_from_sequence_impl(std::index_sequence<Is...>)
    {
        return std::array<std::size_t, sizeof...(Is)>{Is...};
    }
    
    template <typename Seq>
    constexpr auto make_array_from_sequence(Seq)
    {
        return make_array_from_sequence_impl(Seq{});
    }
    

    用法:

    int main()
    {
        constexpr auto arr = make_array_from_sequence(make_sequence<6>());
        static_assert(arr[0] == 0);
        static_assert(arr[1] == 1);
        static_assert(arr[2] == 2);
        static_assert(arr[3] == 4);
        static_assert(arr[4] == 5);
        static_assert(arr[5] == 7);
    }
    

    live example on wandbox.org

    【讨论】:

    • 使用 C++17 构造函数推导,std::array&lt;std::size_t, sizeof...(Is)&gt;{Is...}; 可以简化为 std::array{Is...};
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-13
    • 2016-03-22
    • 1970-01-01
    相关资源
    最近更新 更多