【发布时间】:2020-06-30 21:02:50
【问题描述】:
我正在尝试使用 std::integer_sequence 及其帮助模板 std::index_sequence 来初始化一个固定大小的 POD 结构,它的行为类似于一个容器。每个元素又包含一个固定大小的数组字段。
容器 POD 结构体本质上定义为:
#define ELEM_NAME_SIZE 7
#define CONTAINER_SIZE 20
using Container = struct Container {
int entries;
Element elems[MAX_CONTAINER_SIZE];
};
各个元素是:
using Element = struct Element {
char name[MAX_NAME_CHARS];
bool bFlag;
};
基于question 的答案,我能够使用std::index_sequence 来初始化固定长度Elements。到目前为止一切顺利。
我需要想出一种方法来构造 Container 使用单个固定大小的 const char* - 比如说“ABCDEF”,或者使用固定长度的数组(最大为 ELEM_NAME_SIZE)字符串.
constexpr char gTestNames[3][ELEM_NAME_SIZE] = {
"APPLE", "BEE", "CHAIN"
};
在live coliru code中,这些容器构造函数中的第一个如下:
template<std::size_t N, typename Indices = std::make_index_sequence<N>>
constexpr Container makeContainer(char const (&name)[N]) {
return makeContainer_in(name, Indices{});
}
用这个产量构造并打印出容器的内容:
const auto container = makeContainer("ABCDEF");
std::cout << container << '\n';
输出:
Container: entries(7)[Element:[ABCDEF],,Element:[],,Element:[],,Element:[],,Element:[],,Element:[],,Element:[],,]
但是,使用替代模板函数重载,带有参数gTestNames:
template<std::size_t N, std::size_t NAME_LEN_MAX = ELEM_NAME_SIZE, typename Indices = std::make_index_sequence<N>>
constexpr Container makeContainer(const char(&names)[N][NAME_LEN_MAX]) {
return makeContainer_in(names, Indices{});
}
调用使用:
const auto container1 = makeContainer(gTestNames);
std::cout << container1 << '\n';;
我得到以下错误输出:
main.cpp: In instantiation of 'constexpr Container makeContainer(const char (&)[N][NAME_LEN_MAX]) [with long unsigned int N = 3; long unsigned int NAME_LEN_MAX = 7; Indices = std::integer_sequence<long unsigned int, 0, 1, 2>; Container = Container]':
main.cpp:78:53: required from here
main.cpp:64:28: error: no matching function for call to 'makeContainer_in(const char [3][7], std::integer_sequence<long unsigned int, 0, 1, 2>)'
64 | return makeContainer_in(names, Indices{});
| ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
main.cpp:52:21: note: candidate: 'template<long unsigned int N, long unsigned int ...Is> constexpr Container makeContainer_in(const char (&)[N], std::index_sequence<Is ...>)'
52 | constexpr Container makeContainer_in(char const (&packed)[N], std::index_sequence<Is...>) {
| ^~~~~~~~~~~~~~~~
main.cpp:52:21: note: template argument deduction/substitution failed:
main.cpp:64:28: note: mismatched types 'const char' and 'const char [7]'
64 | return makeContainer_in(names, Indices{});
| ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
如果可能的话,除了纠正我的错误之外,还有什么方法可以简化所有这些样板代码 - 也许使用折叠表达式 - 我想使用 index_sequences(因为我正在尝试学习如何使用它们),但我从来不理解总是将调用转发到某种代理以扩展索引的要求。一定有更简单的方法。
【问题讨论】:
-
using Var = struct Var {};的意义何在?为什么不只是struct Var? -
@KamilCuk 在我有诊断朋友打印机的地方查看完整的 coliru - 这就是为什么我再次表示“基本上”你好我的朋友 :) - 正如你所看到的,我正在努力从你的指导中学习跨度>
-
using Container = struct Container {请不要这样做。你在哪里看到的? -
我需要一个朋友 fn 的前向参考,该参考显示在 coliru 项目中,而不是在问题中
-
@johnco3: template-head 是看起来像
template<…>的句法组件;因为你不能从默认参数中推断出来,所以调用者必须明确地构造了一个std::integer_sequence,这使得调用者成为符合人体工程学的包装器。
标签: c++ c++17 variadic-templates variadic-functions