强制执行编译时constexpr
Enforce compile-time constexpr
在C++11中,我们得到constexpr
:
constexpr int foo (int x) {
return x + 1;
}
是否可以将动态值为x
的foo
调用作为编译时错误?也就是说,我想创建一个foo
,这样就只能传入constexpr
参数。
用元函数替换它:
template <int x> struct foo { static constexpr int value = x + 1; };
用法:
foo<12>::value
不幸的是,除非绝对必要,否则无法保证constexpr
函数,即使是最琐碎的函数,也会被编译器求值。也就是说,除非它出现在编译时需要其值的地方,例如在模板中。为了强制编译器在编译期间进行评估,您可以执行以下操作:
constexpr int foo_implementation (int x) {
return x + 1;
}
#define foo(x) std::integral_constant<int, foo_implementation(x)>::value
然后像往常一样在代码中使用foo
int f = foo(123);
这种方法的好处是它保证了编译时的评估,如果将运行时变量传递给foo
:,则会出现编译错误
int a = 2;
int f = foo(a); /* Error: invalid template argument for 'std::integral_constant',
expected compile-time constant expression */
不太好的地方是它需要一个宏,但如果你想要有保证的编译时评估和漂亮的代码,这在目前看来是不可避免的。(不过我很想被证明是错的!)
是的,现在可以在纯惯用C++中完成,因为C++20增加了对这类问题的支持。使用consteval
对函数进行注释,可以确保在编译时对其进行求值。https://en.cppreference.com/w/cpp/language/consteval
consteval int foo( int x ) {
return x + 1;
}
int main( int argc, char *argv[] )
{
return foo( argc ); // This will not compile
return foo( 1 ); // This works
}
另请参阅3个最相关的编译器中的godbolt.org演示。
我将使用static_assert
,如本例所示
#include<iostream>
constexpr int foo(int x) {
return x+1;
}
int main() {
// Works since its static
std::cout << foo(2) << std::endl;
static_assert(foo(2) || foo(2) == 0, "Not Static");
// Throws an compile error
int in = 3;
std::cout << foo(in) << std::endl;
static_assert(foo(in) || foo(in) == 0, "Not Static");
}
有关更多信息:http://en.cppreference.com/w/cpp/language/static_assert
相关文章:
- 如何确认我的constexpr表达式实际上已经在编译时执行
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- 用于循环编译的 constexpr
- 使用 constexpr 替换 #define 和 #ifdef 进行条件编译
- constexpr 使用 clang 编译 TensorFlow 时出错
- C++ constexpr语言 - 可以在编译时评估值吗?
- 编译时生成应在构造函数中创建的非 constexpr 对象数组
- constexpr 函数在编译时获取值,即使我的变量不是 constexpr
- 如何判断是否在编译时计算了"constexpr"(无需手动检查)
- C++编译时使用 constexpr 字符数组指针分配静态数组?
- Constexpr变量不是编译时值
- C++constexpr编译问题
- 模板;constexpr;编译时间
- 如果ConstexPR编译了错误分支的时间崩溃
- 使用constexpr编译时间哈希
- 仅在constexpr/编译时上下文中操作时,引用是否有用
- 使用 constexpr 编译时间字符串串联
- C++VS2015 constexpr编译错误,constexpr构造函数调用constexpr成员函数
- Constexpr编译错误使用std::acos与clang++而不是g++
- 使用constexpr编译时出错