如果我没记错的话,user defined literal的参数在编译时总是已知的。在C++20中,你可以使用consteval
强制函数在编译时执行,这样throw
就会生成一个编译时错误。
#include <limits>
consteval int operator""_int(unsigned long long int v) {
if (std::numeric_limits<int>::max() < v) {
throw "out of range";
}
return static_cast<int>(v);
}
int main() {
return 1'000'000'000'000_int;
}
$ g++ -std=c++20 main.cpp
main.cpp: In function ‘int main()’:
main.cpp:11:12: in ‘constexpr’ expansion of ‘operator""_int(1000000000000)’
main.cpp:5:9: error: expression ‘<throw-expression>’ is not a constant expression
5 | throw "out of range";
| ^~~~~~~~~~~~~~~~~~~~
根据我的经验,编译时错误通常比运行时错误更可取。
如果在定义中必须调用其他非constexpr
的函数,那么consteval
显然不是一个选项,但除了这种情况,我想不出任何不使用consteval
的理由。
是否有其他原因不将用户定义的文字标记为consteval
?
2条答案
按热度按时间kx5bkwkv1#
用户定义的文字可能返回堆分配的对象,如
std::string
,在这种情况下,不能使用consteval
,因为函数体不是常量表达式。如果实现本身可以用作常量表达式,那么没有充分的理由不使用
consteval
。ykejflvf2#
我唯一能想到的是,它会阻止你做(例如):
但这是相当人为的,你可能永远不会预见到的需要。