Nie*_*eru 21 c++ iterator initializer-list c++11
如果元素std::initializer_list总是const值,为什么我们有模板方法喜欢begin()/end()和不cbegin()/cend()?这个名称(通过惯例,与例如比较std::vector)可以表明,当它们总是返回时,两种std::initializer_list方法都可以iterator返回const_iterator.
And*_*owl 25
虽然除了和之外我无法提供有关其原因cbegin()和cend()不属于std::initializer_list界面的原因的见解,因此有充分的理由说明为什么最后两个成员函数应该存在. begin()end()
例如,一个原因是,基于范围的for循环由C++ 11标准精确地根据函数begin()和end()(第6.5.4/1段)定义.因此,为了能够将它与初始化列表一起使用,std::initializer_list必须提供begin()和end()成员函数:
#include <utility>
#include <iostream>
int main()
{
auto l = { 1, 2, 3, 4, 5 };
for (int x : l) // Works because std::initializer_list provides
// the member functions begin() and end().
{
std::cout << x << " ";
}
}
Run Code Online (Sandbox Code Playgroud)
此外,是有意义的考虑成员函数cbegin()和cend()不存在前C++ 11:因此,具有begin()和end()的界面上std::initializer_list允许作出书面来讲旧通用算法begin()和end()与初始化列表工作,以及,而不需要他们是重写.
你写:
这些名称(通过惯例,与例如比较
std::vector)可以表明,当它们总是返回时,两种std::initializer_list方法都可以iterator返回const_iterator.
实际上,这个比喻不太合适.例如,std::vector函数在非实例(即可变元素,其元素可以被修改,添加和删除)上调用时返回,并且在实例上调用时(即不可变的实例,其内容)不能改变):begin()iteratorconststd::vectorconst_iteratorconst
#include <vector>
#include <type_traits>
int main()
{
// A non-const vector...
std::vector<int> v = { 1, 2, 3, 4, 5 };
auto i = v.begin();
static_assert(
std::is_same<decltype(i), decltype(v)::iterator>::value,
// ^^^^^^^^
// ...non-const iterator!
"What?");
// A const vector...
std::vector<int> const vc = { 1, 2, 3, 4, 5 };
auto ic = vc.begin();
static_assert(
std::is_same<decltype(ic), decltype(vc)::const_iterator>::value,
// ^^^^^^^^^^^^^^
// ...const iterator!
"What?");
}
Run Code Online (Sandbox Code Playgroud)
根据定义,初始化程序列表是不可变集合.根据C++ 11标准的第18.9/2段:
类型的对象
initializer_list<E>提供对类型对象数组的访问const E.[...]
由于初始化列表是集合const的元素,在cbegin()和cend()功能实际上会做同样的事情,begin()而且end()做.
事实上,iterator和const_iterator都定义为指针初始化列表中的值类型的常量元素,所以这是值得商榷的它是否是一个的情况下begin(),并end()总是返回const_iterator(如你假设),或者他们是否总是返回iterator.
这就是C++ 11 Standard的第18.9/1段定义initializer_list类模板的方式:
namespace std {
template<class E> class initializer_list {
public:
typedef E value_type;
// ...
typedef const E* iterator;
typedef const E* const_iterator;
// ...
constexpr const E* begin() const noexcept; // first element
constexpr const E* end() const noexcept; // one past the last element
};
// ...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
668 次 |
| 最近记录: |