So I stumbled on this piece of code and I don't understand why the following construct is not ill-formed.
template<typename T, std::size_t... lst>
struct mystruct : std::index_sequence<lst..., sizeof...(lst)> {
T i;
};
int main() {
mystruct<int> obj;
}
This should be ill-formed since the instantiation of mystruct with T = int will yield the following class(after T is substituted with int):
template<int, std::size_t... lst>
struct mystruct : std::index_sequence<, //Empty list expansion
0> {
int i;
};
How is the std::index_sequence<, 0>
not ill-formed? This above compiles without an error.
An empty parameter pack is never "empty" in a way that would make a construct syntactically invalid.
[temp.variadic]
7 When N is zero, the instantiation of the expansion produces an empty list. Such an instantiation does not alter the syntactic interpretation of the enclosing construct, even in cases where omitting the list entirely would otherwise be ill-formed or would result in an ambiguity in the grammar. [ Example:
template<class... T> struct X : T... { }; template<class... T> void f(T... values) { X<T...> x(values...); } template void f<>(); // OK: X<> has no base classes // x is a variable of type X<> that is value-initialized
— end example ]
So it's not std::index_sequence<, 0>
, but rather std::index_sequence<0>
.
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