用户定义的文字在 C++20 中是否应该始终保持保守?

Ben*_*uch 5 c++ constant-expression user-defined-literals c++20 consteval

如果我没记错的话,用户定义的文字的参数在编译时总是已知的。在 C++20 中,您可以使用强制函数在编译时执行,consteval从而throw生成编译时错误。

\n
#include <limits>\n\nconsteval int operator""_int(unsigned long long int v) {\n    if (std::numeric_limits<int>::max() < v) {\n        throw "out of range";\n    }\n    return static_cast<int>(v);\n}\n\nint main() {\n    return 1\'000\'000\'000\'000_int;\n}\n
Run Code Online (Sandbox Code Playgroud)\n
$ g++ -std=c++20 main.cpp\nmain.cpp: In function \xe2\x80\x98int main()\xe2\x80\x99:\nmain.cpp:11:12:   in \xe2\x80\x98constexpr\xe2\x80\x99 expansion of \xe2\x80\x98operator""_int(1000000000000)\xe2\x80\x99\nmain.cpp:5:9: error: expression \xe2\x80\x98<throw-expression>\xe2\x80\x99 is not a constant expression\n    5 |         throw "out of range";\n      |         ^~~~~~~~~~~~~~~~~~~~\n
Run Code Online (Sandbox Code Playgroud)\n

根据我的经验,编译时错误通常比运行时错误更可取。

\n

如果必须在定义中调用其他不是 的函数constexpr,那么consteval显然不是一个选项。但除了这个例子,我想不出有什么理由不使用consteval.

\n

还有其他原因不将用户定义的文字标记为 吗consteval

\n

康桓瑋*_*康桓瑋 7

用户定义的文字可能会返回堆分配的对象,例如std::string,在这种情况下consteval不能使用,因为函数体不是常量表达式。

如果实现本身可以用作常量表达式,则没有充分的理由不使用consteval.

  • C++20 还使 `std::string` 在编译时可用。但是,“consteval”意味着您无法在运行时使用结果,因为编译时分配不会泄漏到运行时代码中。因此,假设字符串文字必须是“consteval”仍然是一个问题。 (5认同)