[这是我的头个难题,但它对const有效,但对constexpr不起作用,我想知道您是否聪明的人可以解释。用g ++ -std = c ++ 14编译。
struct Service
{
std::string name;
enum {
thread,
interrupt,
end_types
} que_type;
};
const Service namedServices[] =
{
{"abc", Service::thread},
{"efg", Service::thread},
{"hij", Service::interrupt},
{"klm", Service::thread},
{"nop", Service::interrupt},
{"qrs", Service::thread},
{"", Service::end_types}
};
constexpr int thcnt()
{
int cnt = 0;
for (const Service* sp = namedServices; sp->que_type != Service::end_types; sp++) {
if (sp->que_type == Service::thread)
cnt++;
}
return cnt;
}
int main(int argc, char** argv)
{
std::string strs[thcnt()];
...
据我所知,这是正确的。如果我更改为
constexpr Service namedServices[] =
我知道
... error: the type 'const Service []' of constexpr variable 'namedServices' is not literal
};
^
这似乎很奇怪,但也许有充分的理由。也许它将在c ++ 20中修复。
谢谢
namedServices
不是LiteralType,因为它是包含std::string
而不是LiteralType的类的数组。因此,它不能为constexpr
。
请注意,您的thcnt()
函数实际上会导致未定义的行为(无需诊断),因为它没有持续评估的情况,并且std::string strs[thcnt()];
仅在启用了VLA的情况下才通过(默认情况下,gcc会这样做)。
从C ++ 20开始,将出现consteval
specifier而不是UB NDR导致编译错误,consteval
支持。