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

C++ 为什么std::cbegin返回与std::begin相同的类型,c++,iterator,c++14,C++,Iterator,C++14,显示std::cbegin的此签名: template< class C > constexpr auto cbegin( const C& c ) -> decltype(std::begin(c)); 模板 constexpr auto-cbegin(const C&C)->decltype(std::begin(C)); 它不应该返回类似于C::const\u迭代器的东西吗?C是一个const引用,因此std::begin(C)它将返回C::begin()的c

显示
std::cbegin
的此签名:

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

它不应该返回类似于
C::const\u迭代器的东西吗?

C
是一个
const
引用,因此
std::begin(C)
它将返回
C::begin()的
const
重载返回的任何内容。对于标准库类型,这是一个
常量迭代器
。对于数组类型,它是指向
const
的指针


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

std::begin
返回一个
迭代器
常量迭代器
,具体取决于参数是否为
const
,参见标准容器的成员函数声明
begin


std::cbegin
返回
std::begin
返回的内容(通过
decltype
),因此如果您有一个
const
对象,将选择
const
重载,该重载依次返回一个
const\u迭代器
cbegin的实现如下:

template <class C>
auto cbegin(const C& container)->decltype(std::begin(container))
{
   return std::begin(container); // see explanation below
}
现在,看看模板推导是如何发生的。在这种情况下,模板(C类)被推导为向量,
cbegin
(const C&container)的参数被推导为
const vector&
。既然容器本身是常量,它将返回向量begin的常量版本

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

我同意这一页在这方面可能会更清晰一些,不会让人们对此进行推理(就像在给定的答案中所做的那样)。此外,对为何引入cbegin的解释(以保证常数,而不仅仅依赖于参数的常数)可能会有所帮助。
std::vector<int> v1;
std::cbegin(v1); 
iterator begin();
const_iterator begin() const; //This will be used .
const_iterator cbegin() const;