This code fails to compile using MSVC 19.27.29112.0, but works with GCC 10.2.0. C++20 is enabled in both cases:
template <typename T>
struct Blah {
void blah() requires (sizeof(T) == 4);
};
template <typename T>
void Blah<T>::blah() requires (sizeof(T) == 4) {}
int main() {
Blah<int> b;
b.blah();
return 0;
}
error C2511: 'void Blah::blah(void)': overloaded member function not found in 'Blah'
The error only occurs if the requires
depends on the class's template type. For example, requires (sizeof(int) == 4)
works fine. Converting blah()
to a templated function and doing something like requires (sizeof(U) == 4)
also works.
Can anyone confirm this is a compiler bug?
(Too long for a comment.) This looks like a bug, indeed, and I suggest you formally report it.
Curiously enough, the following works, instead.
template <typename T>
struct Blah {
enum { sizeofT = sizeof(T) }; // or: static const size_t sizeofT = sizeof(T);
// or: static constexpr size_t sizeofT = sizeof(T);
void blah() requires (sizeofT == 4);
};
template <typename T>
void Blah<T>::blah() requires (sizeofT == 4) {}
int main() {
Blah<int>().blah(); // ok
Blah<float>().blah(); // ok
// Blah<short>().blah() // c7500: 'blah': no function satisfied its constraints
// Blah<double>().blah(); // c7500: 'blah': no function satisfied its constraints
return 0;
}
Apparently, gcc and clang knows the existent overload in your code (here). However, I think the MS compiler team would have pipelined the memory initialization module at a different stage as compared to gcc and clang. I (kind-of) speculate this since the following code works (i.e., initialize and create memory for the blah() function in the struct template itself):
template<typename T>
struct Blah {
void blah() requires (sizeof(T) == 4) {};
};
int main() {
Blah<int> b;
b.blah();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With