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

时间:2016-09-08 14:17:48

标签: c++ c++11 constexpr

我正在CppCon 2015: Scott Schurr “constexpr: Applications"19'28"他正在展示强制编译时错误的技巧:

  

强制编译时间的方法?

     
      
  • 不在标准范围内
  •   
  • 但是黑客有时会工作
  •   
     

投掷中未解决的符号

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只有编译时错误的动机是什么?

1 个答案:

答案 0 :(得分:3)

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

为什么呢?因为可以在不运行应用程序的情况下修复编译时错误,因此可以很容易地修复。通过抛出未解析的外部符号,您可以强制将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是一个未解析的外部符号,并且每个符号都必须有一个定义,所以你在编译时得到错误 ,即使它不是编译器< em>本身抱怨。