Populate An Array Using Constexpr at Compile-time

后端 未结 4 1789
[愿得一人]
[愿得一人] 2020-11-29 03:32

I would like to populate an array of enum using constexpr. The content of the array follows a certain pattern.

I have an enum separating ASCII character set into fou

4条回答
  •  盖世英雄少女心
    2020-11-29 04:05

    IMHO the best way to do this is simply write a tiny setup program that will generate table for you. And then you can either throw out the setup program, or check it in alongside the generated source code.

    The tricky part of this question is just a duplicate of this other one: Is it possible to create and initialize an array of values using template metaprogramming?

    The trick is, it's impossible to write anything like

    Type table[256] = some_expression();
    

    at file scope, because global arrays can be initialized only with literal (source-level) initializer-lists. You can't initialize a global array with the result of a constexpr function, even if you could somehow get that function to return a std::initializer_list, which you can't because its constructor isn't declared constexpr.

    So what you have to do is get the compiler to generate the array for you, by making it a static const data member of a template class. After one or two levels of metaprogramming that I'm too confused to write out, you'll bottom out in a line that looks something like

    template 
    Type DummyStruct::table[] = { whichCategory(Indices)... };
    

    where Indices is a parameter-pack that looks like 0,1,2,... 254,255. You construct that parameter-pack using a recursive helper template, or maybe just using something out of Boost. And then you can write

    constexpr Type (&table)[] = IndexHelperTemplate<256>::table;
    

    ...But why would you do all that, when the table is only 256 entries that will never change unless ASCII itself changes? The right way is the simplest way: precompute all 256 entries and write out the table explicitly, with no templates, constexpr, or any other magic.

提交回复
热议问题