std::wstring::resize_and_overwrite回调参数与传入值不符问题咨询
问题:std::wstring::resize_and_overwrite回调参数与传入大小不一致的原因
测试代码
#include <iostream> #include <string> int main() { std::wstring ws; for(unsigned i=1;i<64;++i){ std::cout<<i<<' '; ws.resize_and_overwrite(i,[](wchar_t*s,size_t c){std::cout<<c<<'\n';return 0;}); } return 0; }
运行输出
1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 14 9 9 10 10 11 11 12 12 13 13 14 14 15 28 16 16 17 17 18 18 19 19 20 20 21 21 22 22 23 23 24 24 25 25 26 26 27 27 28 28 29 56 30 30 31 31 32 32 33 33 34 34 35 35 36 36 37 37 38 38 39 39 40 40 41 41 42 42 43 43 44 44 45 45 46 46 47 47 48 48 49 49 50 50 51 51 52 52 53 53 54 54 55 55 56 56 57 112 58 58 59 59 60 60 61 61 62 62 63 63
问题分析
按照C++20标准,std::basic_string::resize_and_overwrite的回调函数仅要求返回值介于0和传入的count(即代码中的i)之间即可,返回0是完全合法的操作。你遇到的回调参数c与i不一致的情况,是特定标准库实现的bug——这些实现错误地将字符串的内部容量值而非传入的count参数传递给了回调函数。
这类bug常见于采用“容量翻倍”增长策略的实现中:当需要扩容时,实现会分配当前容量两倍的空间,但错误地将新容量值作为count传给回调,而非用户传入的i。这种行为违反了C++标准的明确规定,标准要求回调必须以用户传入的count值作为第二个参数。
你可以通过修改回调的返回值为i(即实际使用传入的所有空间)验证这一点:此时参数c会与i完全一致,因为实现不会因返回值为0而触发异常的内部状态处理逻辑。
内容的提问来源于stack exchange,提问作者user42471
相关产品推荐
相关产品推荐

