cppreference 显示 std::cbegin
的签名如下:
template< class C >
constexpr auto cbegin( const C& c ) -> decltype(std::begin(c));
它不应该返回像
C::const_iterator
这样的东西吗?cppreference 显示 std::cbegin
的签名如下:
template< class C >
constexpr auto cbegin( const C& c ) -> decltype(std::begin(c));
C::const_iterator
这样的东西吗?c
是一个const
引用,所以std::begin(c)
将返回C::begin()
的const
重载函数返回的任何内容。对于标准库类型,这是一个const_iterator
。对于数组类型,它是一个指向const
的指针。
需要注意的是,这依赖于其他非标准库用户定义的C
,被合理地实现为具有C::begin()
的const
重载函数,该函数返回一个迭代器,让您可以对容器的元素进行const
访问。
std::begin
函数返回一个迭代器或者const迭代器,具体返回哪一种取决于参数是否为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
。
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;