Reputation: 1269
I have here the case that a function could potentially be constexpr. Normally one adds the constexpr and use the constant evaluation only if the context allows it. However the following code complaints despite not using it in a constexpr context:
template <typename T>
struct Wrapper
{
friend constexpr bool operator==(const Wrapper& crLhs, const Wrapper& crRhs) noexcept
{
return crLhs.m_t == crRhs.m_t;
}
T m_t = {};
};
Using Visual Studio 2017 15.9.20 this gives 'error C3615: constexpr function 'operator ==' cannot result in a constant expression' when e.g. instantiated for std::string. The information is correct but I am not instantiating it in a constexpr context.
void f()
{
bool b;
Wrapper<int> a;
b = a == a; //ok
Wrapper<std::string> c;
b = c == c; //C3615, but not using constexpr context
}
I can apply a workaround it by using a member template or drop the constexpr but is there fancy trick here to have the best of both worlds (i.e. constexpr when applicable)?
Upvotes: 3
Views: 341
Reputation: 10740
This bug was fixed in MSVC version 19.22, and compiles without error. Here we can see a side-by-side of the two compiler versions: https://godbolt.org/z/79kXFm
All versions after and including 19.22 compiles it, but Version 19.21 and below incorrectly give you error C3615, even though both of them are set to use C++11.
The bug was only ever in MSVC, and even very old versions of GCC and Clang compile the code without giving you an error.
If possible, you should just move to a newer version of Visual Studio. This is the simplest option to upgrade the compiler, and if you move to a newer version the compiler should receive bug fixes and upgrades. If that's not an option, I would google different ways to upgrade just the compiler itself. This might be helpful.
Upvotes: 3