I am trying to use std::integer_sequence
and its helper template std::index_sequence
to initialize a fixed size POD struct that behaves like a container. Each element in turn contains a fixed size array field.
The container POD struct is essentially defined as:
#define ELEM_NAME_SIZE 7
#define CONTAINER_SIZE 20
using Container = struct Container {
int entries;
Element elems[MAX_CONTAINER_SIZE];
};
and the individual elements are:
using Element = struct Element {
char name[MAX_NAME_CHARS];
bool bFlag;
};
Building on the answer to question, I was able to use std::index_sequence
to initialize the fixed length Element
s. So far so good.
I need to come up with a way to construct the Container
with either a single fixed size const char*
- say "ABCDEF", or alternatively with an array of fixed length (up to a max of ELEM_NAME_SIZE) character strings.
constexpr char gTestNames[3][ELEM_NAME_SIZE] = {
"APPLE", "BEE", "CHAIN"
};
In the live coliru code, the first of these container constructors is as follows:
template<std::size_t N, typename Indices = std::make_index_sequence<N>>
constexpr Container makeContainer(char const (&name)[N]) {
return makeContainer_in(name, Indices{});
}
constructing and printing out the contents of the container with this yield:
const auto container = makeContainer("ABCDEF");
std::cout << container << '\n';
with the output:
Container: entries(7)[Element:[ABCDEF],,Element:[],,Element:[],,Element:[],,Element:[],,Element:[],,Element:[],,]
However, using the alternative template function overload, with parameter 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{});
}
Called using:
const auto container1 = makeContainer(gTestNames);
std::cout << container1 << '\n';;
I get the following error output:
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{});
| ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~
If possible, besides correcting the mistake I have, is there some way I could simplify all this boiler plate code - perhaps using fold expressions - I would like to use index_sequences (as I am trying to learn how to use them), but I never understood the requirement to always forward the calls to a sort of proxy in order to expand the indices. There has got to be an easier way.