从std::initializer_list派生是否合法?



我可以使用std::initializer_list列表作为基类吗?

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; 

上面的代码在GCC和Clang中都有效。但它真的有效吗?

cppreference.com对std::initializer_list的定义如下:

template< class T >
class initializer_list;

但是这是否意味着std::initializer_list和其他类一样是普通类呢?我认为它是c++中的一种特殊对象。

我能在标准中找到的最好的参考是§16.4.5.1

以下子句指定对…[程序]使用标准库类作为基类

然后在§16.4.5.5

c++标准库中为基类定义的虚成员函数签名可以在程序中定义的派生类中被重写

这似乎意味着继承stdlib类是公平的。

当然,使用这些子类作为实际的std::initializer_list将是困难的。我能想到的c++中std::initializer_list的每个用例都是逐个值的,所以你的子类在传递给大多数构造函数之前就会被切片。

最新更新