Reputation: 9213
Can I use std::initializer_list
list as a base class?
template <typename T>
struct il : std::initializer_list<T>
{
using base = std::initializer_list<T>;
il(base list): base(list) {}
const T &operator[](size_t i) const
{ return *(base::begin()+i); }
};
void print2(il<int> list)
{
for (size_t i = 0; i < list.size(); i += 2)
{ std::cerr << list[i] << "; "; }
std::cerr << std::endl;
}
int main()
{
print2({0, 1, 2, 3, 4, 5, 6});
}
// The output: 0; 2; 4; 6;
The code above works in both GCC and Clang. But is it actually valid?
The cppreference.com defines std::initializer_list
as follows:
template< class T >
class initializer_list;
But does this mean that std::initializer_list
is an ordinary class like any other? I thought it is kind of special object in C++.
Upvotes: 1
Views: 64
Reputation: 70347
The best reference to this I can find in the standard is §16.4.5.1
The following subclauses specify constraints on ... [the program's] use of standard library classes as base classes
And then later in §16.4.5.5
Virtual member function signatures defined for a base class in the C++ standard library may be overridden in a derived class defined in the program
Which would seem to imply that it's fair game to subclass stdlib classes.
Of course, using those subclasses as an actual std::initializer_list
is going to be difficult. Every use case I can think of in C++ for std::initializer_list
takes one by value, so your subclass is going to get sliced before it ever gets passed to most constructors.
Upvotes: 1