c++ - 为什么强制 constexpr 只有编译时错误?

标签 c++ c++11 constexpr

我在看CppCon 2015: Scott Schurr “constexpr: Applications" , 关于 19'28"他展示了一个只强制编译时错误的技巧:

A Way to Force Compile-Time Only?

  • Not within the standard
  • But a hack that sometimes works

Unresolved Symbol In Throw

extern const char* compile11_bin_invoked_at_runtime;
template <typename T = std::uint32_t>
constexpr T compile11_bin(
  constexpr_txt t,
  std::size_t i = 0, // index
  std::size_t b = 0, // bit count
  T x = 0) // accumulator
{
  return
    i >= t.size() ? x : // end recursion
    b >= std::numeric_limits<T>::digits ?
    throw std::overflow_error("Too many bits!") :
    t[i] == ',' ? compile11_bin<T>(t, i+1, b, x) :
    t[i] == '0' ? compile11_bin<T>(t, i+1, b+1, (x*2)+0) :
    t[i] == '1' ? compile11_bin<T>(t, i+1, b+1, (x*2)+1) :
    throw std::domain_error( // Only '0', '1', and ','
    compile11_bin_invoked_at_runtime);
}

我很好奇,强制 constexpr 只有编译时错误的动机是什么?

最佳答案

编译时错误总是比运行时错误好。

为什么?因为可以在不运行应用程序的情况下修复编译时错误,因此可以轻松修复。通过抛出未解析的外部符号,您可以强制将 compile11_bin 的结果存储在 constexpr 变量中,这使您能够更快地检测到错误。

幻灯片中的示例是:

constexpr auto maskA = constexpr11_bin<std::uint8_t>("1110 0000");
auto maskB = constexpr11_bin<std::uint8_t>("0001 1111");

此处,maskA 会导致编译时错误,该错误很容易修复。另一方面,maskB 会导致运行时错误,因为 maskB 不是 constexpr,因此不必在编译时评估结果,并且您会出现运行时错误。

那是因为 compile11_bin_invoked_at_runtime 是一个未解析的外部符号,每个符号都必须有一个定义,所以你在编译时会得到一个错误,即使它不是提示的编译器本身

关于c++ - 为什么强制 constexpr 只有编译时错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39393362/

相关文章:

c++ - 在 constexpr 构造函数中复制数组

c++ - 在持续评估期间读取其生命周期之外的变量是否可诊断?

c++ - 在 C++ 中重新定义一个非虚函数

c++ - 右值或左值 (const) 引用参数

c++ - 为什么非静态数据成员不能是 constexpr?

c++ - 如何将 std::string 转换为大写?

c++ - 将多个元素以多个偏移量插入到 vector 中

c++ - 如何使用 glUniformMatrix4fv 将 4x4 变换矩阵传递和使用到 vShader 中?

c++ - 如何查看 C 头文件的源代码?

c++ - 使用 QRegExp 的 Ingore 字符串