You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 13:41:25