在C++20中,用户定义的字面值应该总是consteval吗?

dxxyhpgq  于 2023-04-01  发布在  其他
关注(0)|答案(2)|浏览(113)

如果我没记错的话,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

kx5bkwkv

kx5bkwkv1#

用户定义的文字可能返回堆分配的对象,如std::string,在这种情况下,不能使用consteval,因为函数体不是常量表达式。
如果实现本身可以用作常量表达式,那么没有充分的理由不使用consteval

ykejflvf

ykejflvf2#

我唯一能想到的是,它会阻止你做(例如):

int i = 42;
auto x = operator""_int (i);

但这是相当人为的,你可能永远不会预见到的需要。

相关问题