来自initializer_list的构造函数

Constructor from initializer_list

本文关键字:构造函数 list initializer 来自      更新时间:2023-10-16

我正在用 c++ 实现一个容器,实际上是数组的包装器。我不确定如何从initializer_list实现构造函数。我最终得到了这个实现,但在我看来真的很丑陋。因此,可以在由initializer_list初始化的堆中分配数组。还是有一种优雅的方法可以做到这一点?

template <typename T> class sequence {
public:
    sequence (size_t n): _data {new T[n]}, _size {n} {};
    sequence (std::initializer_list<T> source);
    ~sequence() { delete[] _data; };
private:
    pointer     _data;
    size_type   _size;
};
//Initializer list constructor
template <class T> sequence<T>::sequence (std::initializer_list<T> source)
: sequence(source.size()) {
    auto iterator = source.begin();
    for ( int i=0; i < _size; i++) {
        _data[i] = *iterator;
        ++iterator;
    }
};

取决于你要做什么。

如果您实际上需要使用在编译时确定的具有有限大小的序列,请使用 std::array<T,std::size_t> ,它是 C++11 中引入的 C 样式数组(就像您正在实现的数组)的包装器。

但是,正如您在一条评论中所说,您这样做主要是为了教育目的。 在这种情况下,您拥有的是体面的。 语法可以稍微清理一下。 考虑:

//Initializer list constructor
template <class T> 
sequence<T>::sequence (std::initializer_list<T> source)
  : sequence(source.size()) 
{
  auto it = source.begin();
  auto const e = source.cend();
  auto d = data_;
  while (it != e) {
     *d++ = *it++;
  } 
};

这样您就不会明确依赖size()。 您可以考虑通过将ite迭代器转换为"移动"迭代器来提高效率:

auto it = std::make_move_iterator(source.begin());
auto e = std::make_move_iterator(source.end());

这样,每当取消引用时,其值都会强制转换为右值引用,从而允许移动分配。