我可以制作表达式 constexpr 吗?
Can I make expressions constexpr?
我最近写了一些代码,将函数结果打印到 cout
。结果本可以在编译时求值,但不是:
#include <algorithm>
#include <iostream>
constexpr unsigned int gcd(unsigned int u, unsigned int v)
{
// ...
}
int main() {
std::cout << gcd(5, 3) << std::endl;
}
无论出于何种奇怪的原因,这都会编译为:(clang -O3 -std=c++17
)
main:
push r14
push rbx
push rax
mov edi, 5
mov esi, 3
call gcd(unsigned int, unsigned int)
mov esi, eax
...
查看 Compiler Explorer 示例。
我希望编译器在编译时评估 gcd(5, 3)
以避免在运行时浪费周期,这显然是可能的。我知道我可以执行以下操作:
int main() {
constexpr unsigned g = gcd(5, 3);
std::cout << g << std::endl;
}
但是,这是不必要的冗长。我想做的就是这样:
#define CONSTEVAL(expression) // ...
int main() {
std::cout << CONSTEVAL(gcd(5, 3)) << std::endl;
}
是否存在任何类型的内置编译器可以使这个 CONSTEVAL
宏成为可能?甚至更好 - 完全便携的东西?
立即调用 lambda 表达式如何?
#define CONSTEVAL(...) []{ constexpr auto result = __VA_ARGS__; return result; }()
这是生成 constexpr
变量以保存结果并计算变量值的有效方法。
这也可以通过模板完成macro-less,但前提是值可以作为模板参数传递:
template <auto V>
inline constexpr auto consteval_v = V;
用作consteval_v<gcd(5, 3)>
。
我最近写了一些代码,将函数结果打印到 cout
。结果本可以在编译时求值,但不是:
#include <algorithm>
#include <iostream>
constexpr unsigned int gcd(unsigned int u, unsigned int v)
{
// ...
}
int main() {
std::cout << gcd(5, 3) << std::endl;
}
无论出于何种奇怪的原因,这都会编译为:(clang -O3 -std=c++17
)
main:
push r14
push rbx
push rax
mov edi, 5
mov esi, 3
call gcd(unsigned int, unsigned int)
mov esi, eax
...
查看 Compiler Explorer 示例。
我希望编译器在编译时评估 gcd(5, 3)
以避免在运行时浪费周期,这显然是可能的。我知道我可以执行以下操作:
int main() {
constexpr unsigned g = gcd(5, 3);
std::cout << g << std::endl;
}
但是,这是不必要的冗长。我想做的就是这样:
#define CONSTEVAL(expression) // ...
int main() {
std::cout << CONSTEVAL(gcd(5, 3)) << std::endl;
}
是否存在任何类型的内置编译器可以使这个 CONSTEVAL
宏成为可能?甚至更好 - 完全便携的东西?
立即调用 lambda 表达式如何?
#define CONSTEVAL(...) []{ constexpr auto result = __VA_ARGS__; return result; }()
这是生成 constexpr
变量以保存结果并计算变量值的有效方法。
这也可以通过模板完成macro-less,但前提是值可以作为模板参数传递:
template <auto V>
inline constexpr auto consteval_v = V;
用作consteval_v<gcd(5, 3)>
。