为什么 std::cbegin return 与 std::begin 类型相同

Why does std::cbegin return the same type as std::begin

cppreference 显示 std::cbegin 的签名:

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

不应该 return 类似 C::const_iterator 的东西吗?

c 是一个 const 引用,所以 std::begin(c) 它会 return 无论 const 重载 C::begin() returns。对于标准库类型,这是 const_iterator。对于数组类型,它是指向 const.

的指针

请注意,这依赖于用户定义的其他非标准库 C,通过 constC::begin() 的重载合理实现,return 是一个迭代器这使您 const 可以访问容器的元素。

std::begin returns 一个 iterator 或一个 const_iterator,取决于参数是否为 const,参见例如http://en.cppreference.com/w/cpp/iterator/begin and the declaration of a member function begin for a standard container http://en.cppreference.com/w/cpp/container/vector/begin

std::cbegin returns what std::begin returns (通过 decltype),所以如果你有一个 const 对象, const重载被选中,依次returns一个const_iterator.

cbegin 的实现如下:

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

对应的begin如下。

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

这个cbegin模板接受任何类型的参数 表示一个 container-like 数据结构,C,它访问这个参数 通过其 reference-to-const 参数,容器。如果C是一个常规容器 类型(例如 std::vector),容器将是对 const 的引用 该容器的版本(例如,const std::vector&)。调用非成员 const 容器上的 begin 函数(由 C++11 提供)产生一个 const_iterator,那个迭代器就是这个模板 returns.

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

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

现在,看看在这种情况下模板推导是如何发生的,template(class C) 被推导为向量,cbegin (const C& container) 的参数被推导为 const vector<int> & 。现在由于容器本身是常量,它将 return 向量开头的常量版本。

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