C++14 编译时间 std::array 可变参数模板
C++14 compile time std::array with variadic templates
我想使用 c++14 可变参数模板构建编译时查找 table。
此刻我在那里:
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>{});
}
我希望 table 在 std::array
中。每行包含一个 std::array
和 2 列。我被困在 generateTable()
中,我需要以某种方式将我的索引作为模板参数传递给 getRow()
。
这是否可以使用 std::integer_sequence
和模板参数包扩展来实现,还是我需要自己实现递归?
(getRow()
已简化 - 值类型实际上来自模板化类型。Index * Index
只是一个占位符。我需要知道如何使用参数调用 getRow()
包扩展。)
看起来你快到了。仅依靠参数包扩展:
return std::array<std::array<unsigned, 2>, sizeof...(Indices)>
{
getRow<Indices>()...
};
getRow<Indices>()...
行将展开为:
getRow<0>(), getRow<1>(), ..... , getRow<sizeof...(Indices)-1>()
+1 用于 KyleKnoepfel 的解决方案,但我在我的 amd64 linux 中编译您的代码时遇到问题,因为 "error: no matching function for call to 'generateTable'" 和 "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')"
问题是 std::make_index_sequence<kCount>{}
生成了 std::size_t
的序列。如果std::size_t
定义为unsigned int
,一切顺利;如果(就像在我的平台中一样)std::size_t
被定义为 unsigned long
,则以下声明不起作用
template<unsigned... Indices>
constexpr auto generateTable(std::index_sequence<Indices...>)
建议:使用 std::size_t
代替 unsigned
;特别是
template<std::size_t ... Indices>
constexpr auto generateTable(std::index_sequence<Indices...>)
En passant,用 { val1, val2 }
初始化一个 std::array
(只有一级大括号)它在 C++14 中是完全合法的但是(恕我直言)我认为最好使用旧的 (C ++11) 带有双层大括号的语法 ({ { val1, val2 } }
);这是为了向后兼容(如 Wum 所指出的)并避免某些编译器(如 clang++ 3.5)发出烦人的警告。所以我建议在数组declaration/initialization中使用二级大括号,所以
return std::array<unsigned, 2> { { Index, Index * Index } };
和
return std::array<std::array<unsigned, 2>, sizeof...(Indices)>
{ { getRow<Indices>() ... } };
p.s.: 对不起我的英语不好
我想使用 c++14 可变参数模板构建编译时查找 table。 此刻我在那里:
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>{});
}
我希望 table 在 std::array
中。每行包含一个 std::array
和 2 列。我被困在 generateTable()
中,我需要以某种方式将我的索引作为模板参数传递给 getRow()
。
这是否可以使用 std::integer_sequence
和模板参数包扩展来实现,还是我需要自己实现递归?
(getRow()
已简化 - 值类型实际上来自模板化类型。Index * Index
只是一个占位符。我需要知道如何使用参数调用 getRow()
包扩展。)
看起来你快到了。仅依靠参数包扩展:
return std::array<std::array<unsigned, 2>, sizeof...(Indices)>
{
getRow<Indices>()...
};
getRow<Indices>()...
行将展开为:
getRow<0>(), getRow<1>(), ..... , getRow<sizeof...(Indices)-1>()
+1 用于 KyleKnoepfel 的解决方案,但我在我的 amd64 linux 中编译您的代码时遇到问题,因为 "error: no matching function for call to 'generateTable'" 和 "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')"
问题是 std::make_index_sequence<kCount>{}
生成了 std::size_t
的序列。如果std::size_t
定义为unsigned int
,一切顺利;如果(就像在我的平台中一样)std::size_t
被定义为 unsigned long
,则以下声明不起作用
template<unsigned... Indices>
constexpr auto generateTable(std::index_sequence<Indices...>)
建议:使用 std::size_t
代替 unsigned
;特别是
template<std::size_t ... Indices>
constexpr auto generateTable(std::index_sequence<Indices...>)
En passant,用 { val1, val2 }
初始化一个 std::array
(只有一级大括号)它在 C++14 中是完全合法的但是(恕我直言)我认为最好使用旧的 (C ++11) 带有双层大括号的语法 ({ { val1, val2 } }
);这是为了向后兼容(如 Wum 所指出的)并避免某些编译器(如 clang++ 3.5)发出烦人的警告。所以我建议在数组declaration/initialization中使用二级大括号,所以
return std::array<unsigned, 2> { { Index, Index * Index } };
和
return std::array<std::array<unsigned, 2>, sizeof...(Indices)>
{ { getRow<Indices>() ... } };
p.s.: 对不起我的英语不好