I'm using C++ with GCC's C extension for designated inits / designated array initializers and I've come across a bit of a pickle. If I have the following (contrived) example code,
#include <string>
#include <string_view>
struct STRUCTURE {
enum class ENUM { A, B, C };
static constexpr std::string_view STRINGS[] {
[static_cast<int>(ENUM::A)] = "A",
[static_cast<int>(ENUM::B)] = "B",
[static_cast<int>(ENUM::C)] = "C"
};
constexpr std::string_view operator[](ENUM e) const {
return STRINGS[static_cast<int>(e)];
}
};
Everything works as expected. However, if I now template the structure, i.e.
#include <string>
#include <string_view>
template <typename T>
struct STRUCTURE { /*same structure definition*/ };
I get a compile-time error that the C99 designator initializers I have are not integral constant expressions.
In fact, in some cases with namespaces I get an internal compiler error / internal compiler segfault, leading me to believe this is an internal issue, but I cannot confirm such.
If I move the scoped enum class outside of the template, everything works again. In that manner, I can simply add a level of indirection to my actual code, however I would prefer not doing so.
Even odder: Say I change the type of the internal array to int
s. I.e,
struct STRUCTURE {
enum class ENUM { A, B, C };
static constexpr int INTS[] {
[static_cast<int>(ENUM::A)] = 65,
[static_cast<int>(ENUM::B)] = 66,
[static_cast<int>(ENUM::C)] = 67
};
constexpr int operator[](ENUM e) const {
return INTS[static_cast<int>(e)];
}
};
I have the same issue. But now if I assign the values via static casts of the enum as the designators are, i.e,
...
static constexpr int INTS[] {
[static_cast<int>(ENUM::A)] = static_cast<int>(ENUM::A),
[static_cast<int>(ENUM::B)] = static_cast<int>(ENUM::B),
[static_cast<int>(ENUM::C)] = static_cast<int>(ENUM::C)
};
...
This works, template or not. Godbolt for this, too.