简体   繁体   English

C ++ 14使用可变参数模板编译时间std :: array

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM