boost::begin处理右值boost::span返回const指针是否为Bug?
Boost 1.78中boost::begin()处理右值boost::span的异常问题
使用Boost 1.78版本的boost::span(对应std::span的实现)时,发现一个异常行为:对右值boost::span调用boost::begin()会返回const指针,这直接破坏了boost::fill(returns_a_span(), 0);这类常见使用场景。
测试代码
以下代码用于验证各调用方式返回的迭代器类型(无需编译,通过编译器报错获取类型信息):
#include <vector> #include <boost/core/span.hpp> #include <boost/range/begin.hpp> template <typename T> struct ErrorType; int main() { std::vector<unsigned char> vec{ 1, 2, 3, 4, 5 }; boost::span<unsigned char> sp{ vec }; ErrorType< decltype( std::begin(sp) ) > e1; ErrorType< decltype( std::begin(std::move(sp)) ) > e2; ErrorType< decltype( boost::begin(sp) ) > e3; ErrorType< decltype( boost::begin(std::move(sp)) ) > e4; ErrorType< decltype( sp.begin() ) > e5; ErrorType< decltype( std::move(sp).begin() ) > e6; return 0; }
编译输出
spantest.cc: In function int main(): spantest.cc:13:44: error: aggregate ErrorType<unsigned char*> e1 has incomplete type and cannot be defined ErrorType< decltype( std::begin(sp) ) > e1; ^~ spantest.cc:14:55: error: aggregate ErrorType<unsigned char*> e2 has incomplete type and cannot be defined ErrorType< decltype( std::begin(std::move(sp)) ) > e2; ^~ spantest.cc:15:46: error: aggregate ErrorType<unsigned char*> e3 has incomplete type and cannot be defined ErrorType< decltype( boost::begin(sp) ) > e3; ^~ spantest.cc:16:57: error: aggregate ErrorType<const unsigned char*> e4 has incomplete type and cannot be defined ErrorType< decltype( boost::begin(std::move(sp)) ) > e4; ^~ spantest.cc:17:40: error: aggregate ErrorType<unsigned char*> e5 has incomplete type and cannot be defined ErrorType< decltype( sp.begin() ) > e5; ^~ spantest.cc:18:51: error: aggregate ErrorType<unsigned char*> e6 has incomplete type and cannot be defined ErrorType< decltype( std::move(sp).begin() ) > e6;
核心观察与疑问
类型未完成是预期设计,目的是让编译器输出迭代器类型信息。关键问题在于e4:对右值span调用boost::begin()返回const unsigned char*,但直接调用成员函数begin()(e6)或std::begin()(e2)都能返回非const指针。
需要明确:
- 这是
boost::begin()的Bug,还是对Boost范围机制存在理解误区? - 除了始终将span转为左值使用外,是否有其他可行的解决方案?
补充背景
该问题与《std::begin and R-values》的议题密切相关,目前std::begin()已修复了右值处理的问题,但boost::begin()仍存在此缺陷。由于Boost范围算法会显式调用boost::begin(),这导致它们无法正常处理非const数据的右值span。
按理解,如果boost::begin()没有右值重载,会匹配const左值引用重载,但疑惑为何boost::span和其他迭代器范围表现不同——此前使用Boost范围算法处理右值范围从未遇到过这种情况。
内容的提问来源于stack exchange,提问作者user1806566
相关产品推荐
相关产品推荐

