为什么强制constexpr只有编译时错误
Why force constexpr have compile time error only?
我正在观看CppCon 2015: Scott Schurr " constexpr: Applications",在19'28"他展示了一个只强制编译时错误的技巧:
一种强制编译时的方法?
- 不符合标准
- 但是一个hack有时是有效的
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
是一个未解析的外部符号,每个符号都必须有一个定义,所以你在编译时得到一个错误,即使它不是编译器本身抱怨。
相关文章:
- 在缺少函数重载时抛出异常,并带有 std::variant 而不是编译时错误
- 如何在常量计算表达式中获取编译时错误?
- C++根据调用的构造函数强制编译时错误
- C++编译时使用 constexpr 字符数组指针分配静态数组?
- 使用 std::iterator_traits<> 时编译时错误不明确
- is_same和variadic模板编译时错误无效转换
- 私有运营商删除会触发 GCC 和 Clang 的编译时错误,但不会在 MSVC 上触发编译时错误
- 运行时与编译时多态性:更好的可读性与编译时错误检查,更重要的是
- 引发编译时错误
- 在编译时通过 constexpr 或模板函数获取多维 std::array 的大小
- 为什么调用不明确的 ctor 时没有编译时错误?
- 在 sizeof 运算符上强制编译时错误
- 未经授权的私有类成员访问会产生编译时错误而不是运行时错误?
- 从Mac上的终端编译时C 错误
- 使用MINGW-W64使用-M32选项(32位代码)编译时错误
- C++线程错误 - 带有类参数的编译时错误
- 如果编译时间构量参数是错误的,则生成编译时错误
- 尝试调用指向成员函数的函数指针时出现编译时错误
- 编译时错误:删除了联合默认构造函数
- 为什么强制constexpr只有编译时错误