c++ - 是否有一种非间接、非 hack 的方法来保证 constexpr 函数只能在编译时调用?

标签 c++ constexpr

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

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.

其中,我们保证所有四个都可以在编译时求值。

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 函数提供同样的保证。

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.

有可能use indirection to provide an effective guarantee that a given constexpr function can only be called at compile time ,但是如果直接访问该函数而不是通过间接帮助程序访问该函数(如链接答案的评论中所述),则此保证将失效。也可以 poison a constexpr function这样就不可能在运行时调用它,by throwing an undefined symbol ,从而通过笨拙的黑客提供这种保证。然而,这些似乎都不是最佳选择。


考虑到这一点,我的问题是:包括当前标准、C++20 草案、正在考虑的提案、实验性功能以及任何其他类似的东西,是否有一种方法可以在不诉诸黑客或间接的情况下提供这种保证,仅使用内置于语言本身和/或正在考虑内置于语言本身的功能和工具? [例如,例如(理论上)[[compile_time_only]][[no_runtime]] 等属性,std::is_constant_evaluated 的用法,或者一个概念,也许?]

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

最佳答案

添加了 C++20 consteval为了这个明确的目的。 consteval 函数是一个 constexpr 函数,保证只在编译时调用。

关于c++ - 是否有一种非间接、非 hack 的方法来保证 constexpr 函数只能在编译时调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57084483/

相关文章:

c++ - 问题 C++ STD 迭代器比较运算符

c++ - 如何在 3d 中将原点设置在左下角

c++ - 我如何围绕概念和不完整类型的限制进行设计?

c++ - 如何检查 const 数组成员在编译时是否单调增长

c++ - 模板推导指南可以调用 constexpr 函数吗?

C++ - Static_assert 和 constexpr 函数在运行时评估的能力

c++ - Boost::filesystem::is_symlink() 不起作用

c++ - OpenCL 内核中的运算符重载

c++ - 带有 constexpr 的编译时数组

c++ - 具有复杂类型且 N=256/large 的 std::array<T, N>