2015-04-07 175 views
7

cppreference显示了这个签名std::cbegin为什么的std :: CBEGIN返回相同类型的std ::开始

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

难道不应该返回类似C::const_iterator呢?

+0

我同意这个页面可能会更清晰一点,不会让人对它做出推理(就像给出的答案中所做的那样)。另外,为什么引入cbegin(以保证常量而不仅仅依赖于参数的常量)可能会有所帮助。 – stefaanv

回答

12

cconst参考,所以std::begin(c)它将返回的C::begin()回报无论const超载。对于标准库类型,这是一个const_iterator。对于数组类型,它是指向const的指针。

请注意,这依赖于定义C,其他非标准库用户与一const过载C::begin()返回一个迭代器,让您const进入容器中的元素三立执行。

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,以及它通过其参考给const参数,容器访问这一论点 。如果C是常规容器 类型(例如,std :: vector),则容器将是对该容器的const 版本的引用(例如,const std :: vector &)。在const容器上调用nonmember begin函数(由C++ 11提供)会产生一个 const_iterator,并且该迭代器就是该模板返回的内容。

例如,如果我已经使用vector作为参数cbegin像下面一样。

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

现在,看看如何演绎模板在这种情况下发生的,模板(C类)被推断为推断为const vector<int> &载体和cbegin(常量ç&容器)的参数。现在因为容器本身是恒定的,它将返回矢量开始的恒定版本。

iterator begin(); 
const_iterator begin() const; //This will be used . 
const_iterator cbegin() const; 
相关问题