非成员函数begin()/cbegin()及其constexpr特性

4
C++11引入了没有constexpr说明符的std :: begin()非成员函数,然后C ++ 14更新为数组类型(T(&)[N])的constexpr-std :: begin()并附加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)

因此,我们可以在C++14的constexpr函数中使用std::begin()和/或std::cbegin()来处理原始数组类型T[N](保留HTML标记)。

问题:

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

1
std::cbegin 调用 std::begin,但它不是 constexpr 的...有两个例外:初始化列表重载和数组。 - T.C.
2
对于问题#2,如果您将其删除,则不再具有原始数组cbeginconstexpr - Ben Voigt
1个回答

3

目前标准库中对于 constexpr 的支持相当有限。

  1. std::begin 非成员函数没有被标记为 constexpr,因为除了 arrayinitializer_list 之外,没有标准容器(或类似容器实体例如 bitset)支持 constexpr 成员函数 begin()(主要是因为某些实现希望使用动态内存分配来进行迭代器调试)。您的解释是正确的。
  2. 非成员函数 std::cbegin 被标记为 constexpr 是为了支持当前两个 constexprstd::begin 非成员函数,用于 arrayinitializer_list,同时也为了向未来标准库升级做好兼容准备。

关于第二点,这对于用户定义的类似容器实体并不是很有用,因为在那里,通常的惯例是在包围用户定义类型的命名空间中定义非成员函数 begin()end(),而不是在 namespace std 中定义。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接