一般而言,对变量或对象使用括号初始化的方式被称为直接初始化,其本质是调用了相应的构造函数;而使用等号初始化的方式则被称为拷贝初始化,说到拷贝大家可能马上就会想到拷贝构造函数、operator =()函数,但此时并不一定是调用了这两个函数,这点极容易混淆!!!
今天正在看侯捷《C++ 新标准 C++11-14》的视频,里面讲到 std::initializer_list 的实现原理,并且把源码贴出来。
/// initializer_list
template<class _E>
class initializer_list
{
public:
typedef _E value_type;
typedef const _E& reference;
typedef const _E& const_reference;
typedef size_t size_type;
typedef const _E* iterator;
typedef const _E* const_iterator;
private:
iterator _M_array;
size_type _M_len;
// The compiler can call a private constructor.
constexpr initializer_list(const_iterator __a, size_type __l)
: _M_array(__a), _M_len(__l) { }
constexpr initializer_list() noexcept
: _M_array(0), _M_len(0) { }
// Number of elements.
constexpr size_type
size() const noexcept { return _M_len; }
// First element.
constexpr const_iterator
begin() const noexcept { return _M_array; }
// One past the last element.
end() const noexcept { return begin() + size(); }
};
他认为,构造 std::initializer_list 之前编译器会先构造一个 std::array,然后使用 std::array 的 begin() 和 size() 构造 std::initializer_list。这种说法有一处错误。编译器不会构造 std::array,而是在栈上直接构造一个数组 const T[N]。在栈上构造的数组会像其他变量一样,在离开作用域时自动析构,不需要手动管理内存,所以根本没必要使用 std::array。
这个是 cppreference.com 的描述:
The underlying array is a temporary array of type
const T[N]
明确地说是普通的 array。
这个是 N3337 的描述:
An object of type
initializer_list<E>provides access to an array of objects of typeconst E.
并没有说是 std::array。
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

评论(0)