constexpr 函数中的 for 循环无法使用 MSVC 19.23 进行编译
For loop in constexpr function fails to compile with MSVC 19.23
以下代码在 Clang 和 GCC 中编译,但在 MSVC 中失败。
template <typename... FieldsSequence>
struct S {
static constexpr bool checkIdUniqueness()
{
using IdType = int;
constexpr IdType fieldIds[sizeof...(FieldsSequence)]{ 0 };
for (size_t i = 0; i < std::size(fieldIds) - 1; ++i)
{
if (fieldIds[i] > fieldIds[i + 1])
{
constexpr auto tmp = fieldIds[i];
fieldIds[i] = fieldIds[i + 1];
fieldIds[i + 1] = tmp;
}
}
return true;
}
};
错误消息是:
expression did not evaluate to a constant
note: failure was caused by a read of a variable outside its lifetime
note: see usage of 'i'
有没有办法让这三个编译器都工作?最终,我需要对数组进行气泡排序,以便在编译时断言所有值都是唯一的。
https://godbolt.org/z/9XbP6-
你过度使用了constexpr
声明。首先,如果fieldIds
被声明为constexpr
那么它也是常量,你不能改变它。至于tmp
,因为它被声明constexpr
初始值设定项必须是一个常量表达式,但它实际上不能是一个。
正确的方法是从这些声明中删除constexpr
:
template <typename... FieldsSequence>
struct S {
static constexpr bool checkIdUniqueness()
{
using IdType = int;
IdType fieldIds[sizeof...(FieldsSequence)]{ 0 };
for (size_t i = 0; i < std::size(fieldIds) - 1; ++i)
{
if (fieldIds[i] > fieldIds[i + 1])
{
auto tmp = fieldIds[i];
fieldIds[i] = fieldIds[i + 1];
fieldIds[i + 1] = tmp;
}
}
return true;
}
};
整个函数仍然可以在常量表达式中计算,但现在对这些变量没有额外的要求,可能会干扰它们的声明或使用。
相关文章:
- 为什么使用__LINE_的代码在发布模式下在MSVC下编译,而不是在调试模式下
- 为什么 gcc 编译这个而 msvc 没有
- std::vector::p ush_back() 不会在 MSVC 上编译具有已删除移动构造函数的对象
- MSVC 无法编译 SFINAE 检查
- 可变参数模板未在 MSVC 中编译?
- MSVC 2010 编译应用程序和 MSVC 2019 编译应用程序之间的行为差异
- 如何使用CLion和MSVC编译器工具链编译wxWidgets Hello World应用程序而没有错误?
- 使用 msvc 15 在 Qt5.13 中编译 CUDA 代码
- std::value templated 方法的函数使用 clang 和 g++ 进行编译,但不使用 msvc 进行编译
- 使用MSVC编译的Qt程序在app.exec()上崩溃
- 使用 MSVC 编译时,msdpb* 文件的正确用法是什么?
- constexpr 函数中的 for 循环无法使用 MSVC 19.23 进行编译
- variadic模板代码中的GCC VS MSVC编译误差
- 为什么"int & const" MSVC 编译得很好?
- 为什么使用 MSVC 编译这个不正确的 std::函数初始化?
- mingw 编译错误:从 'FARPROC ' 到 'void*' 的转换无效,但 msvc 编译正常
- Boost Spirit代码,可与msvc编译,但与gcc编译错误
- 为什么下面的代码使用 MSVC++ 编译
- 在MinGW编译的项目中使用MSVC编译的Boost二进制文件
- 我怎么能摆脱*.exe.从MSVC编译的exe文件中获取manifest文件