gpt4 book ai didi

c++ - 从 constexpr 数组创建可变参数模板

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:43:57 26 4
gpt4 key购买 nike

假设我们有以下类型

template <bool... Values>
struct foo{};

我想从 constexpr 数组 bool tab[N] 创建一个可变参数模板。换句话说,我想做类似的事情:

constexpr bool tab[3] = {true,false,true};
using ty1 = foo<tab[0], tab[1], tab[2]>;

但我想以编程方式进行。现在,我尝试了以下方法:

template <std::size_t N, std::size_t... I>
auto
mk_foo_ty(const bool (&tab)[N], std::index_sequence<I...>)
{
// error: template argument for template type parameter must be a type
return foo<tab[I]...>{};
}

// error (see mk_foo_ty)
using ty2 = decltype(mk_ty(tab, std::make_index_sequence<3>{}));

// error: expected '(' for function-style cast or type construction
using ty3 = foo<(tab[std::make_index_sequence<3>])...>;

我什至不确定这是否可能。也许求助于 Boost.Preprocessor 之类的东西,但我不喜欢这个主意。那么,有人有想法吗?谢谢!

编辑

一方面,我有一个 constexpr bool 方阵的框架,可以在编译时使用异或、取反等创建。

另一方面,我有一个模板框架,它使用 bool 值作为参数使用在可变参数模板中编码的信息静态创建操作。

我的目标是弥合这两个框架之间的差距。因此,我不能使用硬编码解决方案。

编辑 2

我发现这个 question 有同样的问题和一个很好的答案,它非常接近 T.C.'s one(使用指针)。 extern 链接也很重要。

但是,我意识到我忘记了一个关键要素。我的 bool 数组包含在 matrix 结构中,以便能够重载运算符 ^、| 等:

template <std::size_t N>
struct matrix
{
const bool data_[N*N];

template<typename... Values>
constexpr matrix(Values... values) noexcept
: data_{static_cast<bool>(values)...}
{}

constexpr bool operator [](std::size_t index) const noexcept
{
return data_[index];
}
}

因此,如果我们应用 T.C 的解决方案:

template<std::size_t N, const bool (&Tab)[N], class>
struct ty1_helper;

template<std::size_t N, const bool (&Tab)[N], std::size_t... Is>
struct ty1_helper<N, Tab, std::index_sequence<Is...>>
{
using type = foo<Tab[Is]...>;
};

template<std::size_t N, const bool (&Tab)[N]>
using ty1 = typename ty1_helper<N, Tab, std::make_index_sequence<N>>::type;

编译器提示传递了一个非类型参数:

// error: non-type template argument does not refer to any declaration
// using t = make_output_template<m.data_, std::make_index_sequence<3>>;
// ^~~~~~~
using t = ty1<3, m.data_>;

最佳答案

我在上面的评论中使用的是全局 constexpr具有外部链接的变量(由于 GCC 的不一致外部链接要求,请参阅 bug 52036 ),如果将它放在标题中并将标题包含在不同的翻译单元中,可能会在链接时显着爆炸。仅适用于一个翻译单元的解决方案并不是很好的解决方案。一种解决方法是将矩阵存储为类的静态数据成员。

struct matrix_holder {
static constexpr matrix<2> mat = {true, false, true, false};
};

template<std::size_t N, const matrix<N> &Mat, class>
struct ty1_helper;

template<std::size_t N, const matrix<N> &Mat, std::size_t... Is>
struct ty1_helper<N, Mat, std::index_sequence<Is...>> {
using type = foo<Mat[Is]...>;
};

template<std::size_t N, const matrix<N> &Mat>
using ty1 = typename ty1_helper<N, Mat, std::make_index_sequence<N*N>>::type;

static_assert(std::is_same<ty1<2, matrix_holder::mat>,
foo<true, false, true, false>>::value, "Oops");

Demo .此外,由于使用 matrix_holder::matty1<2, matrix_holder::mat>算作 ODR 使用,要完全符合要求,您应该提供一个定义:

constexpr matrix<2> matrix_holder::mat;

关于c++ - 从 constexpr 数组创建可变参数模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27589563/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com