如何在编译时将同质元组转换为数组?

How to convert a homogenous tuple to an array at compile time?

我想先说明一下,当我说同质元组时,我的意思是每个元素的类型都相同,或者每个元素都有一个 public 成员,它在所有元素中都是相同的类型元素。在这种情况下,public 成员也需要是 static constexpr.

这是描述我的问题的一段简化代码:

#include <cstddef>
#include <tuple>
#include <type_traits>
#include <utility>

template <std::size_t N>
struct Int : std::integral_constant<std::size_t, N>
{
    Int() = default;
    Int(const Int&) = delete;
    Int(Int&&) = delete;

    Int& operator=(const Int&) = delete;
    Int& operator=(Int&&) = delete;
};

template <std::size_t... Ns>
struct Stuff
{
    using type = std::tuple<Int<Ns>...>;
    using arr_type = std::array<std::size_t, std::tuple_size_v<type>>;
    static constexpr arr_type arr = {Ns...};
};

我相当确定它是正确的,唯一的问题是最后一行,但希望你能理解要点。

现在,数组是使用 Ns... 构建的。我希望能够从 type 构建数组(原因是 type 已经从元组中删除了重复类型(基于 .value)并且也有在此代码的实际版本中排序的类型(基于 .value)。相反,如果在编译时从数组中排序和删除重复值更容易,那么这也将被接受为答案。

所以理想情况下,我会编写某种模板化结构来创建数组(因为在结构中会有一个 static constexpr arr_type value = 成员),而在 Stuff 结构中,我会初始化 arr 像这样的成员:

static constexpr arr_type arr = detail::make_array_v<type>;

如果绝对必要,我愿意取消对 Int 结构的复制 construction/assignment 的限制。我不确定如何为此编写帮助程序 function/struct,感谢任何帮助。答案可以使用任何版本的 c++,包括 c++20。

我认为这以某种通用的方式解决了您的问题:

namespace detail {

    template <class Tuple>
    struct make_array;

    template <class V, template <V N> class C, V... Ns>
    struct make_array<std::tuple<C<Ns>... >> {
        static constexpr std::array value{Ns... };
    };

    template <class Tuple>
    constexpr auto make_array_v = make_array<Tuple>::value;

}

它基本上是一个模板,具有 std::tuple 专门化 std::tuple 具有值列表的给定模板参数。

以下是可能的用法(假设 CharcharInt bur 相似):

constexpr auto arr1 = detail::make_array_v<std::tuple<Int<42>, Int<38>, Int<57>>>;
static_assert(arr1 == std::array<std::size_t, 3>{42, 38, 57});

constexpr auto arr2 = detail::make_array_v<std::tuple<Char<'A'>, Char<'Z'>,
                                                      Char<'w'>, Char<'U'>>>;
static_assert(arr2 == std::array{'A', 'Z', 'w', 'U'});

该实现对 C++17 有效,我认为转换为 C++14 非常容易(您只需为 value 指定模板参数)。上面的测试需要 C++20 用于 std::array.

constexpr 比较运算符

完整 godbolt.org 示例代码:https://godbolt.org/z/jkiA9R