[英]C++14 compile time std::array with variadic templates
I'd like to build a compile time lookup table using c++14 variadic templates. 我想使用c ++ 14可变参数模板构建编译时查找表。 At the moment I'm there:
目前我在那里:
static const unsigned kCount = 5;
template<unsigned Index>
constexpr auto getRow(void)
{
return std::array<unsigned, 2> { Index, Index * Index };
}
template<unsigned... Indices>
constexpr auto generateTable(std::index_sequence<Indices...>)
{
return std::array<std::array<unsigned, 2>, sizeof...(Indices)>
{
// This is were I'm stuck. How to build a std::array using Indices as template parameter in getRow()?
};
}
constexpr auto generate(void)
{
return generateTable(std::make_index_sequence<kCount>{});
}
I want the table to be in a std::array
. 我希望表在
std::array
。 Each row consists of a std::array
with 2 columns. 每行包含一个带有2列的
std::array
。 I'm stuck in generateTable()
where I need to somehow pass my Indices to getRow()
as a template parameter. 我陷入了
generateTable()
,我需要以某种方式将我的Indices传递给getRow()
作为模板参数。
Is this achievable using std::integer_sequence
and template parameter pack expansion or do I need to implement the recursion on my own? 这可以使用
std::integer_sequence
和模板参数包扩展来实现,还是我需要自己实现递归?
( getRow()
is simplified - the value types are actually coming from templated types. Index * Index
is just a placeholder. I need to know the way how to call getRow()
using parameter pack expansion.) (
getRow()
被简化 - 值类型实际上来自模板类型。 Index * Index
只是一个占位符。我需要知道如何使用参数包扩展调用getRow()
。)
Looks like you're almost there. 看起来你几乎就在那里。 Just rely on parameter-pack expansion:
只需依靠参数包扩展:
return std::array<std::array<unsigned, 2>, sizeof...(Indices)>
{
getRow<Indices>()...
};
where the getRow<Indices>()...
line will expand to: 其中
getRow<Indices>()...
行将扩展为:
getRow<0>(), getRow<1>(), ..... , getRow<sizeof...(Indices)-1>()
+1 for the solution of KyleKnoepfel but I have problems compiling your code in my amd64 linux because "error: no matching function for call to 'generateTable'" and "candidate template ignored: substitution failure : deduced non-type template argument does not have the same type as the its corresponding template parameter ('unsigned long' vs 'unsigned int')" +1为KyleKnoepfel的解决方案,但我在amd64 linux中编译代码时出现问题,因为“错误:没有匹配函数来调用'generateTable'”和“候选模板被忽略:替换失败:推断出的非类型模板参数没有与其对应的模板参数相同的类型('unsigned long'vs' unsigned int')“
The problem is that std::make_index_sequence<kCount>{}
generate a sequence of std::size_t
. 问题是
std::make_index_sequence<kCount>{}
生成一系列std::size_t
。 If std::size_t
is defined as unsigned int
, all goes well; 如果将
std::size_t
定义为unsigned int
,则一切顺利; if (like in my platform) std::size_t
is defined as unsigned long
, the following declaration didn't work 如果(在我的平台中)
std::size_t
被定义为unsigned long
,则以下声明不起作用
template<unsigned... Indices>
constexpr auto generateTable(std::index_sequence<Indices...>)
Suggestion: use ever std::size_t
instead unsigned
; 建议:使用
std::size_t
而不是unsigned
; particularly 尤其
template<std::size_t ... Indices>
constexpr auto generateTable(std::index_sequence<Indices...>)
En passant, initialize a std::array
with { val1, val2 }
(only one level of braces) it's perfectly legal in C++14 but (IMHO) I think it's better to use the old (C++11) syntax with a double level of braces ( { { val1, val2 } }
); En passant,用
{ val1, val2 }
(只有一个大括号)初始化一个std::array
它在C ++ 14中是完全合法的但是(恕我直言)我认为最好使用旧的(C ++ 11)语法双层括号( { { val1, val2 } }
); this for backwards compatibility (as pointed by Wum) and to avoid annoying warnings with some compilers (like clang++ 3.5). 这是为了向后兼容(如Wum所指出的)并避免使用某些编译器(如clang ++ 3.5)发出恼人的警告。 So I suggest to use a second level of braces in array declaration/initialization, so
所以我建议在数组声明/初始化中使用第二级括号,所以
return std::array<unsigned, 2> { { Index, Index * Index } };
and 和
return std::array<std::array<unsigned, 2>, sizeof...(Indices)>
{ { getRow<Indices>() ... } };
ps: sorry for my bad English. ps:抱歉我的英语不好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.