为什么constexpr不会导致编译超出索引范围而失败

问题描述

我在c ++项目中编写了一个小的辅助函数,该函数应该将enum的值转换为预定的字符串列表。我这样写:

#include <stdint.h>
#include <iostream>

enum things{
    val1 = 0,val2,val3,val4
};

constexpr const char* things_strings[4] = {"A","B","C","D"}; 

constexpr const char* get_thing_string(const things thing){
    return things_strings[static_cast<uint32_t>(thing)];
}

int main(){
  std::cout << get_thing_string(things::val1);
  std::cout << get_thing_string(static_cast<things>(12));
}

我希望这会使编译失败。我认为通过使用constexpr可以防止在编译期间出现索引超出范围的问题。有没有一种方法可以在C ++ 11中强制执行?

解决方法

是的,但是您正在运行时调用该函数。如果您在编译时上下文中调用此函数,例如通过分配一个constexpr变量,您将得到一个编译时错误:

constexpr auto c = get_thing_string(static_cast<things>(12));  // error

这里是demo


请注意,在c ++ 20中,您可以创建函数consteval,然后在所有情况下编译都会失败,因为必须在编译时对函数 进行评估。

这里是demo