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 函数)。
问题:
- C++14 不允许在 constexpr 上下文中对"标准容器"(如
std::array
)进行非成员std::begin()
,因为它们不提供 constexpr-begin()
成员函数。我的解释正确吗? - 为什么非会员
std::cbegin()
有constexpr
说明符?对于用户提供的具有 constexpr-begin()
成员功能的容器?
标准库中当前的constexpr
支持确实相当有限。
- 非成员
std::begin
没有标记为constexpr
因为除了array
和initializer-list
之外,没有标准容器(或类似容器的实体,如bitset
)支持constexpr
成员begin()
(主要是因为一些实现希望使用迭代器调试使用动态内存分配)。你在这里的解释是正确的。 - 非成员
std::cbegin
被标记为constexpr
,以支持(目前)array
和initializer_list
的两个constexpr
std::begin
非成员功能,并为标准库中的未来升级向前兼容。
关于第 2 点,它对于用户定义的容器类实体不是那么有用,因为那里接受的习惯用法是在用户定义类型周围的命名空间中定义非成员begin()
和end()
,而不是在 namespace std
中。