是否有非间接,非破解的方式来保证constexpr函数仅在编译时可调用? [英] Is there a non-indirection, non-hack way to guarantee that a constexpr function only be callable at compile time?

查看:78
本文介绍了是否有非间接,非破解的方式来保证constexpr函数仅在编译时可调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前,我们有两个主要的编译时评估选项:模板元编程(通常使用模板结构和/或变量)和 constexpr 操作 1

At the moment, we have two primary options for compile-time evaluation: template metaprogramming (generally using template structs and/or variables), and constexpr operations1.

template<int l, int r> struct sum_ { enum { value = l + r }; }; // With struct.
template<int l, int r> const int sum = sum_<l, r>::value;       // With struct & var.
template<int l, int r> const int sub = l - r;                   // With var.
constexpr int mul(int l, int r) { return l * r; }               // With constexpr.

我们保证可以在编译时对所有这四个值进行评估。

Of these, we are guaranteed that all four can be evaluated at compile time.

template<int> struct CompileTimeEvaluable {};

CompileTimeEvaluable<sum_<2, 2>::value> template_struct;                 // Valid.
CompileTimeEvaluable<sum<2, 2>>         template_struct_with_helper_var; // Valid.
CompileTimeEvaluable<sub<2, 2>>         template_var;                    // Valid.
CompileTimeEvaluable<mul(2, 2)>         constexpr_func;                  // Valid.

我们还可以保证前三个将仅在编译时可评估。时间,由于模板的编译时性质;但是,我们不能为 constexpr 函数提供相同的保证。

We can also guarantee that the first three will only be evaluable at compile time, due to the compile-time nature of templates; we cannot, however, provide this same guarantee for constexpr functions.

int s1 = sum_<1, 2>::value;
//int s2 = sum_<s1, 12>::value; // Error, value of i not known at compile time.

int sv1 = sum<3, 4>;
//int sv2 = sum<s1, 34>;        // Error, value of i not known at compile time.

int v1 = sub<5, 6>;
//int v2 = sub<v1, 56>;         // Error, value of i not known at compile time.

int c1 = mul(7, 8);
int c2 = mul(c1, 78);           // Valid, and executed at run time.

可以使用间接提供了有效保证,给定的 constexpr 函数只能在编译时调用,但是这种保证如果直接(而不是通过间接帮助器)访问函数(如链接的答案的注释中所述),则中断。也可以毒化 constexpr 函数,以便对其进行调用通过抛出添加一个未定义的符号,从而为笨拙的黑客提供了保证。

It is possible to use indirection to provide an effective guarantee that a given constexpr function can only be called at compile time, but this guarantee breaks if the function is accessed directly instead of through the indirection helpers (as noted in the linked answer's comments). It is also possible to poison a constexpr function such that calling it at runtime becomes impossible, by throwing an undefined symbol, thus providing this guarantee by awkward hack. Neither of these seems optimal, however.

考虑到这一点,我的问题是:包括当前的标准C ++ 20草案,正在考虑的提案,实验性功能以及任何其他种类,有一种方法可以仅使用内置和/或考虑内置在语言本身中的功能和工具来提供这种保证,而无需借助黑客或间接手段? [例如,诸如(均为理论上的) [[compile_time_only]] [[no_runtime]] std :: is_constant_evaluated 或概念的用法?

Considering this, my question is thus: Including current standards, C++20 drafts, proposals under consideration, experimental features, and anything else of the sort, is there a way to provide this guarantee without resorting to hacks or indirection, using only features and tools built into and/or under consideration for being built into the language itself? [Such as, for example, an attribute such as (both theoretical) [[compile_time_only]] or [[no_runtime]], usage of std::is_constant_evaluated, or a concept, perhaps?]

1:从技术上来说,宏也是一种选择,但是...是的,不是。

推荐答案

C ++ 20已添加 consteval 用于此明确目的。 consteval 函数是 constexpr 函数,保证只能在编译时调用。

C++20 added consteval for this express purpose. A consteval function is a constexpr function that is guaranteed to be only called at compile time.

这篇关于是否有非间接,非破解的方式来保证constexpr函数仅在编译时可调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆