When throwing T::v of type int into t<>, I would expect N to be created by use of n's converting constructor. However, for some reason GCC seems to look for member i in c<int, 3>::v. What does the C++20 standard say about this type of construction or deduction for non-type template parameters?
#include <concepts>
template<auto...>
struct n {
constexpr n(int x): i{x} {}
int i;
};
template<typename T, T V>
struct c { static constexpr T v = V; };
template<n N>
using t = c<decltype(N.i), N.i>;
// clang ok, gcc nope, msvc ok
static_assert([]<typename T = t<3>>
{ return std::same_as<T, t<T::v>>; }());
Live example
The error message from GCC:
<source>: In instantiation of '<lambda()> [with T = c<int, 3>]':
<source>:15:41: required from here
<source>:15:19: error: request for member 'i' in 'c<int, 3>::v', which is of
non-class type 'const int'
15 | { return std::same_as<T, t<T::v>>; }());
| ~~~~~^~~~~~~~~~~~~~~~~~~
As per the comments, your understanding is correct and this is definitely a GCC bug. Strictly, the answer to the question is that C++20 says unfortunately little about how the template parameter object is initialized. A defect report has just been approved; until that link works the previous version is available.
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