Jiř*_*ner 5 c++ constructor initializer-list
我正在用 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;
}
};
Run Code Online (Sandbox Code Playgroud)
取决于你想做什么。
如果您确实需要使用在编译时确定的大小有界的序列,则使用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++;
}
};
Run Code Online (Sandbox Code Playgroud)
这样你就不会明确依赖size(). 您可以考虑通过将it和e迭代器转换为“移动”迭代器来提高效率:
auto it = std::make_move_iterator(source.begin());
auto e = std::make_move_iterator(source.end());
Run Code Online (Sandbox Code Playgroud)
这样,无论何时取消引用,其值都会转换为右值引用,从而允许进行移动分配。