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



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

引自 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::array)进行非成员std::begin(),因为它们不提供 constexpr- begin()成员函数。我的解释正确吗?
  2. 为什么非会员std::cbegin()constexpr说明符?对于用户提供的具有 constexpr- begin()成员功能的容器?

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

  1. 非成员std::begin没有标记为constexpr因为除了arrayinitializer-list之外,没有标准容器(或类似容器的实体,如bitset)支持constexpr成员begin()(主要是因为一些实现希望使用迭代器调试使用动态内存分配)。你在这里的解释是正确的。
  2. 非成员std::cbegin被标记为constexpr,以支持(目前)arrayinitializer_list的两个constexpr std::begin非成员功能,并为标准库中的未来升级向前兼容。

关于第 2 点,它对于用户定义的容器类实体不是那么有用,因为那里接受的习惯用法是在用户定义类型周围的命名空间中定义非成员begin()end(),而不是在 namespace std 中。

最新更新