简体   繁体   中英

Is it legal to derive from std::initializer_list?

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++.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM