【问题标题】:C++17 Iterate over a subset of parameter packC ++ 17迭代参数包的子集
【发布时间】:2020-05-05 20:22:06
【问题描述】:

我有一个接收参数包的结构。假设参数包的大小永远不会小于 3。此外,结构中的std::array 应该在编译时进行评估。我想使用参数包填充数组,但我想跳过第一个和最后一个元素。

这是我的代码:

#include <iostream>
#include <array>
#include <cstdint>

template<int32_t ...Ts>
struct St {
    const std::array<int32_t, sizeof...(Ts)-2U> arr{};
};

int main() {
    constexpr St<7, 2, 1, 5, 6> s;
    std::cout << s.arr[2] << std::endl;

    return 0;
}

理想情况下,我想使用带有 [1, sizeof_parameter_pack - 1] 或 [0, size_of_parameter_pack - 2] 的元素的 std::index_sequence 和折叠表达式来填充数组。但是,我正在努力创建 index_sequence。我不希望结构接收另一个模板参数。我怎样才能做到这一点?

【问题讨论】:

  • 我可能误解了一些东西,但我认为arr 应该是 const 因为会有更多相同结构的对象
  • 对不起,我的错误。修好了!

标签: c++ algorithm templates c++17 metaprogramming


【解决方案1】:

std::index_sequence 的可能解决方案:

template<int32_t... Ts>
struct St {
    static constexpr auto Size = sizeof...(Ts) - 2;
    const std::array<int32_t, Size> arr;

    constexpr St() : St(std::array{Ts...}, std::make_index_sequence<Size>{}) {}

private:
    template<class Arr, std::size_t... I>
    constexpr St(Arr init, std::index_sequence<is...>) : arr{init[I + 1]...} {}
};

【讨论】:

    【解决方案2】:

    我认为最简单的方法是执行以下操作:

    #include <iostream>
    #include <array>
    #include <cstdint>
    
    template<uint32_t... Ts>
    constexpr std::array<int32_t, sizeof...(Ts)-1> create_arr() {
        const std::array<int32_t, sizeof...(Ts)> tmp{Ts...};
        std::array<int32_t, sizeof...(Ts)-1> ret{};
        // With C++20, this is a call to std::copy
        for(auto i = 0ul; i != tmp.size()-1; ++i) {
            ret[i] = tmp[i];
        }
        return ret;
    }
    template<uint32_t first, uint32_t ...Ts>
    struct St {
        const std::array<int32_t, sizeof...(Ts)-1> arr = create_arr<Ts...>();
    };
    
    int main() {
        constexpr St<7U, 2U, 1U, 5U, 6U> s;
        std::cout << s.arr[2] << std::endl;
    
        return 0;
    }
    

    这可以在运行时进行评估(如果您的 St 对象不是 constexpr),您可以通过声明数组成员 constexpr 来解决这个问题。

    顺便说一句:您确定要从uint32_t 初始化int32_t 数组吗?

    【讨论】:

    • 我把 uint32_t 换成了 int32_t,谢谢你的注意!
    猜你喜欢
    • 1970-01-01
    • 2018-06-20
    • 2021-08-16
    • 1970-01-01
    • 1970-01-01
    • 2019-08-30
    • 1970-01-01
    • 1970-01-01
    • 2021-04-03
    相关资源
    最近更新 更多