为何链式std::ranges::views的大小会出现差异化增长?
std::ranges::views链式组合时视图大小变化的原因探究
测试std::ranges::views链式组合时,发现视图大小变化存在以下现象:
- 视图迭代器每次链式后固定增加8字节
transform视图本身大小无增长,filter视图的增长幅度却无规律- MSVC编译器下的变化模式略有不同,但同样难以预测
测试代码
#include <iostream> #include <ranges> #include <string> int main() { static constexpr auto printed = [](auto&& v) { std::cout << "sizeof(v): " << sizeof(v) << ", "; std::cout << "sizeof(it): " << sizeof(v.begin()) << ", "; std::cout << "values: { "; for (auto&& x : v) { std::cout << x << ", "; } std::cout << "}\n"; return v; }; using namespace std::ranges::views; auto hundred = printed(iota(0ull, 100ull)); auto small = printed(hundred | filter([](auto i) { return i < 50; })); auto times_seven = printed(small | transform([](auto i) { return i * 7; })); auto even = printed(times_seven | filter([](auto i) { return i % 2 == 0; })); auto as_string = printed(even | transform([](auto i) { return std::to_string(i); })); auto no_twos = printed(as_string | filter([](auto s) { return s.find('2') == s.npos; })); }
测试结果
| view | sizeof(it) | delta | sizeof(view), GCC/Clang | delta | sizeof(view), MSVC | delta |
|---|---|---|---|---|---|---|
| iota | 8 | 16 | 16 | |||
| filter | 16 | 8 | 32 | 16 | 48 | 32 |
| transform | 24 | 8 | 32 | 0 | 64 | 16 |
| filter | 32 | 8 | 64 | 32 | 112 | 48 |
| transform | 40 | 8 | 64 | 0 | 128 | 16 |
| filter | 48 | 8 | 112 | 48 | 192 | 64 |
疑问
虽然代码并未存储视图,无需关心其大小,但疑惑为何视图大小不能仅依赖lambda的大小(本次测试中lambda均为空)。尝试查看标准库源码,但因多层基类、模板特化及概念约束难以读懂,特此咨询该现象的原因。
内容的提问来源于stack exchange,提问作者Dominik Kaszewski
相关产品推荐
相关产品推荐

