I need to create an array of static data, where the size (and data) is known at compile time, but differs between build configurations.
This is a very dumbed-down version of what I’m trying to do
(Please ignore glaring bad practices in this code as it is just an example):
constexpr ProductType PRODUCT = ProductType::A;
constexpr size_t dataSize() { return PRODUCT == ProductType::A ? 3 : 4; }
constexpr std::array<int, dataSize()> createArray()
{
if constexpr (dataSize() == 4) {
return std::array<int, dataSize()>{1, 2, 3, 4};
} else {
return std::array<int, dataSize()>{1, 2, 3};
}
}
But this code fails to compile. The first branch of the constexpr-if is still evaluated and deemed invalid:
<source>:22:54: error: too many initializers for 'std::array<int, 3>'
22 | return std::array<int, dataSize()>{1, 2, 3, 4};
| ^
But reading the docs I was under the impression that the code in the non-active branch of constexpr-if can contain code that will return wrong type, so why wouldn’t this work?
>Solution :
The condition you pass to if constexpr does not depend on any template parameters, so both branches are compiled.
Outside a template, a discarded statement is fully checked.
if constexpris not a substitute for the#ifpreprocessing directivevoid f() { if constexpr(false) { int i = 0; int *p = i; // Error even though in discarded statement } }