EDIT: this was a compiler issue and has now been resolved by Microsoft. Refer to https://developercommunity.visualstudio.com/t/C-compiler-regression-constexpr-constr/10677725.
I would please like some help understanding why the following code does not compile in MSVC (/std:c++20) but does in GCC and Clang. Seems to be related to the constexpr constructor maybe.
#include <iostream>
#include <array>
class TestX
{
bool GetA(char * outVal, unsigned int outValLen) {(void)outVal, (void)outValLen; return false;}
struct SupportedParam
{
using GetParamFunc = bool (TestX::*)(char * outVal, unsigned int outValLen);
constexpr SupportedParam(GetParamFunc gp) : GetParam(gp) {}
GetParamFunc GetParam;
};
static const auto & SupportedParameters()
{
static constexpr std::array<SupportedParam,1> t =
{
SupportedParam(&TestX::GetA)
};
static_assert(t[0].GetParam == &TestX::GetA);
return t;
};
public:
void Print()
{
for(auto & x : SupportedParameters())
{
std::cout << (this->*x.GetParam)(nullptr, 0);
}
}
};
int main(void)
{
TestX x;
x.Print();
}
This seems to be a regression/bug in the latest msvc version starting from 19.36.
As a workaround you could define SupportedParameters
outside TestX
as shown below:
class TestX
{
//other code as before
//this is a declaration
static const std::array<SupportedParam,1>& SupportedParameters();
public:
//other code as before
};
//out of class definition workaround
const std::array<TestX::SupportedParam,1>& TestX::SupportedParameters()
{
static constexpr std::array<SupportedParam,1> t =
{
SupportedParam(&TestX::GetA)
};
static_assert(t[0].GetParam == &TestX::GetA);
return t;
}