非成员函数begin()/ cbegin()及其constexpr-ness

时间:2015-02-03 01:01:28

标签: c++ c++14 constexpr

C ++ 11引入了std::begin()非成员函数,没有constexpr - 说明符,然后C ++ 14更新到constexpr - std::begin()表示数组类型(T (&)[N]并附加constexpr - std::cbegin()用于通用容器类型(const C&)。

来自http://en.cppreference.com/w/cpp/iterator/begin

template< class T, size_t N >
constexpr T* begin( T (&array)[N] );  // (since C++14)

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

因此,我们可以在constexpr上下文中使用std::begin()和/或std::cbegin()来获取原始数组类型T[N](对于C ++ 14 constexpr函数)。

问题:

  1. C ++ 14不允许constexpr上下文中的非成员std::begin()用于“标准容器”,例如std::array,因为它们不提供constexpr - begin()成员函数。我的解释是否正确?
  2. 为什么非会员std::cbegin()constexpr - 说明符?对于具有constexpr - begin()成员函数的用户提供的容器?

1 个答案:

答案 0 :(得分:3)

标准库中的当前constexpr支持确实相当有限。

  1. 非成员std::begin未标记为constexpr,因为除了arrayinitializer-list之外,没有标准容器(或像bitset这样的容器之类的容器)支持constexpr 1}} member begin()(主要是因为某些实现想要使用动态内存分配来使用迭代器调试)。你的解释是正确的。
  2. 非会员std::cbegin已标记为constexpr,以支持constexpr和{{}的{当前}两个std::begin array非会员功能1}},并且可以向前兼容标准库中的未来升级。
  3. 关于第2点,它对于用户定义的容器(如实体)没那么有用,因为接受的习惯用法是在用户周围的命名空间中定义非成员initializer_listbegin() - 已定义的类型,而不是end()