当前位置: 首页 > 知识库问答 >
问题:

如何将编译时STD::数组“扩展”到参数包中?

訾旭
2023-03-14

我想使用部分模板专门化,以便将数组(在编译时创建)“分解”为由其值组成的参数包(以便与我在代码中定义的其他结构接口)。以下内容(我的第一次尝试)不编译

#include <array>

template <typename T, auto k> struct K;
template <typename T, std::size_t... A> struct K<T, std::array<std::size_t, sizeof...(A)>{A...}> {};

因为模板参数std::array {A...} 不得涉及模板参数。正如我所理解的,在部分模板专门化中提供非类型参数是不可能的,如果它们不是非常依赖于模板参数的话。因此,我试图通过在类型中包含值来解决这个问题:

#include <array>

template <auto f> struct any_type;

template <typename T, typename array_wrapper> struct FromArr;
template <typename T, std::size_t... A>
struct FromArr<T, any_type<std::array<std::size_t, sizeof...(A)>{A...}>> {};

int main() {
  FromArr<int, any_type<std::array<std::size_t, 2>{1, 2}>> d;
  (void) d;
}
file.cc: In function ‘int main()’:
file.cc:10:55: error: aggregate ‘FromArr<int, Any<std::array<long unsigned int, 2>{std::__array_traits<long unsigned int, 2>::_Type{1, 2}}> > d’ has incomplete type and cannot be defined
  10  |   FromArr<int, Any<std::array<std::size_t, 2>{1, 2}>> d;

我使用g++-10.0(GCC)10.0.1202124(实验性)并通过g++-std=c++2a文件进行编译。cc,因为我使用非类型模板参数,所以需要c++2a。

在我的实际代码中,我得到了一个依赖于参数包(1)的结构。如果我能够使用数组(2)(我在另一段代码中作为非类型模板参数获得了它)与该结构接口,那就太好了,如下面的代码所示。

template <int... s> struct toBeUsed;                               // (1)
template <std::size_t s, std::array<int, s> arr> struct Consumer { // (2)
    toBeUsed<arr> instance; // This is what I would like to do
}

我的尝试是像上面的fromstruct那样编写一个helper struct,我可以用数组实例化该结构,其中我有一个typedeffromstruct::type,它提供了具有正确参数的tobeused,类似于这个示例,它完成了我在这里要用std::tuple组成的类型所做的工作。

这里我链接了简化的用法示例(第二个代码块)。

共有1个答案

姜华翰
2023-03-14

受@dfri回答的启发,我将她/他的解决方案转换为一个可以省略函数的版本,而是只使用一个结构,对std::integer_sequence使用部分模板专门化,这可能也会引起其他人的兴趣:

template <auto arr, template <typename X, X...> typename Consumer,
          typename IS = decltype(std::make_index_sequence<arr.size()>())> struct Generator;

template <auto arr, template <typename X, X...> typename Consumer, std::size_t... I>
struct Generator<arr, Consumer, std::index_sequence<I...>> {
  using type = Consumer<typename decltype(arr)::value_type, arr[I]...>;
};
#include <array>

/// Structure which wants to consume the array via a parameter pack.
template <typename StructuralType, StructuralType... s> struct ConsumerStruct {
  constexpr auto operator()() const { return std::array{s...}; }
};

/// Solution
template <auto arr, template <typename X, X...> typename Consumer,
          typename IS = decltype(std::make_index_sequence<arr.size()>())> struct Generator;

template <auto arr, template <typename X, X...> typename Consumer, std::size_t... I>
struct Generator<arr, Consumer, std::index_sequence<I...>> {
  using type = Consumer<typename decltype(arr)::value_type, arr[I]...>;
};

/// Helper typename
template <auto arr, template <typename T, T...> typename Consumer>
using Generator_t = typename Generator<arr, Consumer>::type;

// Usage
int main() {
  constexpr auto tup = std::array<int, 3>{{1, 5, 42}};
  constexpr Generator_t<tup, ConsumerStruct> tt;
  static_assert(tt() == tup);
  return 0;
}
 类似资料:
  • 问题内容: 有没有办法将Python元组扩展为函数-作为实际参数? 例如,这里做了魔术: 我知道可以将其定义,但是当然可能会有遗留代码。谢谢 问题答案: 不正是你要求什么。的*操作者只需解包元组(或任何可迭代),并把它们作为位置函数的自变量。有关更多信息,请参见此处。 侧问题:不要为你的标识符内建类型的名称,如使用,,,,等等-这是可怕的做法,它会回来,咬你的时候,你最不经意的时候,所以只是进入的

  • 问题内容: 我知道您不能动态扩展普通数组,但这是一种有效的方法吗? 我知道比尝试使用普通数组更好的方法,但是我想首先使用普通数组来解决这个问题。 我的愿望是,它从0 + 1(so 1)开始,在被称为new时,它的大小与相同,然后保持不变,同时再次声明,然后将其复制回新的大小。这对我来说很有意义,但我总是会遇到异常情况? 问题答案: 该方法不会更改OrigArray的值;它所做的只是在其中存储一个克

  • 问题内容: 我有一个具有形状的数组,以及一个具有形状的数组。 如何将这两个形状附加为一个数组? 我试过了,但它没有保持尺寸,而该选项导致。 问题答案: 用途: 这可以处理数组具有不同维数的情况,并沿第三轴堆叠数组。 否则,要使用或,您必须自己制作三维尺寸并指定要在其上连接的轴:

  • 我被困了几个小时,试图找出为什么以下代码无法编译,如果有人能指出我错过了什么,我将不胜感激。 代码只是我在实际项目代码中遇到的编译问题的一个简化示例。 这个问题似乎与“A”有关 使用gcc(C 17)编译。我收到的错误如下所示:

  • 问题 你想编写一个C扩展函数来操作数组,可能是被array模块或类似Numpy库所创建。 不过,你想让你的函数更加通用,而不是针对某个特定的库所生成的数组。 解决方案 为了能让接受和处理数组具有可移植性,你需要使用到 Buffer Protocol . 下面是一个手写的C扩展函数例子, 用来接受数组数据并调用本章开篇部分的 avg(double *buf, int len) 函数: /* Call

  • 扩展说明 Java 代码编译器,用于动态生成字节码,加速调用。 扩展接口 org.apache.dubbo.common.compiler.Compiler 扩展配置 自动加载 已知扩展 org.apache.dubbo.common.compiler.support.JdkCompiler org.apache.dubbo.common.compiler.support.JavassistCom