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

7

cppreference 显示 std::cbegin 的签名如下:

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

它不应该返回像 C::const_iterator 这样的东西吗?

我认为页面上可能需要更清晰地说明这一点,而不是让人们像给出的答案那样去推理。此外,解释为什么引入cbegin(为了保证const性,而不仅仅依赖于参数的const性)可能会有所帮助。 - stefaanv
3个回答

12

c是一个const引用,所以std::begin(c)将返回C::begin()const重载函数返回的任何内容。对于标准库类型,这是一个const_iterator。对于数组类型,它是一个指向const的指针。

需要注意的是,这依赖于其他非标准库用户定义的C,被合理地实现为具有C::begin()const重载函数,该函数返回一个迭代器,让您可以对容器的元素进行const访问。


3

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参数container访问该参数。如果C是传统的容器类型(例如std::vector),container将是对该容器的const版本的引用(例如const std::vector&)。在const容器上调用非成员begin函数(由C++11提供)会产生一个const_iterator,而这个迭代器就是此模板返回的内容。

例如,如果我已经使用向量作为cbegin的参数,如下所示。

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

现在,让我们看一下模板推导在这种情况下如何进行。模板(类C)被推断为向量,cbegin的参数(const C& container)被推断为const vector<int> &。由于容器本身是常量,它将返回向量的常量版本的开始。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接