为什么std :: cbegin返回与std :: begin相同的类型

时间:2015-04-07 07:37:44

标签: c++ iterator c++14

cppreference显示std::cbegin的签名:

template< class C >
constexpr auto cbegin( const C& c ) -> decltype(std::begin(c));

不应该返回类似C::const_iterator的内容吗?

3 个答案:

答案 0 :(得分:12)

cconst引用,因此std::begin(c)它会返回const C::begin()重载返回的内容。对于标准库类型,这是const_iterator。对于数组类型,它是指向const的指针。

请注意,这依赖于其他非标准库用户定义的C,通过const重载实现C::begin(),它会返回一个迭代器,为您提供const访问容器的元素。

答案 1 :(得分:3)

std::begin会返回iteratorconst_iterator,具体取决于参数是否为const,请参阅例如http://en.cppreference.com/w/cpp/iterator/begin以及标准容器http://en.cppreference.com/w/cpp/container/vector/begin的成员函数begin的声明

std::cbegin返回std::begin返回的内容(通过decltype),因此如果您有const个对象,则会选择const重载,返回const_iterator

答案 2 :(得分:2)

cbegin的实现如下:

template <class C>
auto cbegin(const C& container)->decltype(std::begin(container))
{
   return std::begin(container); // see explanation below
}

对应的开头如下。

template< class C > 
auto begin( C& c ) -> decltype(c.begin()); //calling container's begin

此cbegin模板接受任何类型的参数 表示类似容器的数据结构C,它访问该参数 通过它的reference-to-const参数,容器。如果C是传统的容器 type(例如,std :: vector),容器将是对const的引用 该容器的版本(例如,const std :: vector&amp;)。调用非成员 在const容器上开始函数(由C ++ 11提供)产生一个 const_iterator,迭代器就是这个模板返回的内容。

例如,如果我使用vector作为cbegin的参数,如下所示。

std::vector<int> v1;
std::cbegin(v1); 

现在,看看在这种情况下模板推导是如何发生的,模板(C类)推导为cbegin(const C&amp;容器)的矢量和参数推导为const vector<int> &。现在,由于容器本身是常量,它将返回向量的开始的常量版本。

iterator begin();
const_iterator begin() const; //This will be used .
const_iterator cbegin() const;