Mar*_*k R 5 c++ visual-c++ constexpr c++17
为多个平台构建的大型 C++17 项目。必须支持 MSVC、clang 和 gcc
以下代码在 MSCV 上失败,但对于其他编译器来说没问题。
#include <algorithm>
#include <initializer_list>
#define FOO_1 1
#define FOO_2 2
#define FOO_3 3
class Baz {
static constexpr auto data = {FOO_1, FOO_2, FOO_3};
static constexpr auto copy_max = std::max({FOO_1, FOO_2, FOO_3});
static constexpr auto data_max = std::max(data);
void bar(std::initializer_list<int>);
void test();
};
void Baz::test()
{ bar(data); }
Run Code Online (Sandbox Code Playgroud)
https://godbolt.org/z/7nv3z3rMY
FOO_x
宏用于外部库。Baz
是我的代码。现在我需要data_max
一些逻辑,我希望在编译时计算它。
作为一种解决方法,我引入了copy_max
由重复代码初始化的方法,这是不好的(有很多值和列表可以更改),也data
可以在运行时代码中使用。
显然问题仅存在于 msvc 19.29(安装在我的机器上)旧版本没有此问题。
有没有一种方法可以在不使用额外的宏或重复代码的情况下以某种方式克服这个问题?我尝试使用std::max_element
自 C++17 以来的 constexpr ,具有相同的结果。这是一个已知的错误还是我应该提交新的错误?
好消息是该错误已在 Visual Studio 2022 版本 17.6 中修复:https://developercommunity.visualstudio.com/t/Fail-to-evaluate-valid-constant-expressi/1622722
但是,如果仍然需要针对旧版本 Visual Studio 的解决方法,则可以使用std::initializer_list<T>
MSVC 中存在的额外构造函数:
constexpr initializer_list(const _Elem* _First_arg, const _Elem* _Last_arg) noexcept
: _First(_First_arg), _Last(_Last_arg) {}
Run Code Online (Sandbox Code Playgroud)
std::initializer_list
从数组构造:
#include <algorithm>
// standard approach, but does not work in MSVC before v19.36
constexpr std::initializer_list<int> a{ 1, 2, 3 };
constexpr auto amax = std::max( a );
static_assert( amax == 3 );
//workaround for MSVC before v19.36
constexpr int x[3] = { 1, 2, 3 };
constexpr std::initializer_list<int> b( x + 0, x + 3 );
constexpr auto bmax = std::max( b );
static_assert( bmax == 3 );
Run Code Online (Sandbox Code Playgroud)
在线演示: https: //gcc.godbolt.org/z/7MhznGd66