Visual C++ constexpr Hints

Visual C++ constexpr Hints

本文关键字:Hints constexpr C++ Visual      更新时间:2023-10-16

Visual C++因忽略constexpr函数限定符而臭名昭著,除非绝对需要。查看以下功能:

constexpr int multiply(int l, int r) noexcept
{
return l * r;
}

根据标准,Visual C++完全允许在编译时不评估右值:

auto three_times_four = multiply(3, 4);

我一直在使用的变通方法是这种丑陋的力量:

constexpr auto constexpr_three_times_four = ;
auto not_constexpr_three_times_four = constexpr_three_times_four;
// use not_constexpr_three_times_four in non-constexpr contexts
// alternatively:
template<auto val>
inline constexpr auto ensure_constexpr = val;
auto not_constexpr_three_times_four = ensure_constexpr<multiply(3, 4)>;

有没有一种方法可以提示编译器,这些东西应该在编译时进行评估?

我对以下内容特别恼火:

namespace l
{
constexpr ::std::uint32_t operator""_crc32(const char * p, ::std::size_t const size) noexcept
{
return crc32(p);
}
}
//...
using namespace l;
search("foo"_crc32);//You don't want to evaluate this at runtime? too bad.

那么,在这种情况下,我该怎么做才能提示编译器并避免这些丑陋的修复呢?

没有机制"提示";向编译器(任何编译器(提供CCD_ 1函数";应该";在编译时调用。constexpr不是的。它不是一个加速代码执行的工具。这是一个允许您进行在编译时需要完成的计算的工具。

C++20允许将函数指定为consteval,这确保了函数必须在常量表达式中执行。但即使是这个功能也不是为了性能;这样他们就可以添加语言的新特性(如反射值(,这些特性只能在编译时存在,并且不能泄漏到运行时代码中。

C++20的constinit允许您声明非常量表达式变量,其初始值设定项必须是常量表达式。这是C++最接近constexpr-即性能的特性。

但除此之外,如果编译器的更高优化级别在编译时没有调用这些函数,那么编译器就是这样选择实现该功能的。