为什么Ranges库中的std::views::take_while需要const谓词?
TL; DR:我玩弄范围和相应的一系列的适配器从范围图书馆。范围适配器std::views::take_while和std::views::filter谓词都从输入序列中排除某些元素。为什么take_while采取const谓词而filter没有?
背景故事
我有一个std::vector<int>并想对其进行迭代,但我想在击中时停止迭代5。通过使用范围适配器,std::views::take_while我可以实现如下:
std::vector<int> v { 8, 2, 5, 6 };
for (int i : v | std::views::take_while([](int i) { return i != 5; })) {
std::cout << "Value: " << i << std::endl;
}
输出:
价值:8
价值:2
但是,我现在也想处理5,因此循环必须进一步运行一个迭代步骤。我没有找到合适的范围适配器,所以我写了以下有状态的 lambda 表达式:
auto cond = [b = true](int i) mutable {
return b ? b = (i != 5), true : false;
};
此 lambda 表达式会记住何时i != 5违反条件并false在下一次调用时返回。然后我将它传递给std::views::take_while如下:
for (int i : v | std::views::take_while(cond)) {
std::cout << "Value: " << i << std::endl;
}
但是,对于上面的代码,编译器会抛出很长的错误信息。由于找不到问题,我仔细检查了声明,std::views::take_while发现谓词Pred必须是const. 寻找替代方案,我检查了std::views::filter. 有趣的Pred是,并不需要在const这里。所以我将上面的可变 lambda 传递给范围适配器std::views::filter,如下所示:
for (int i : v | std::views::filter(cond)) {
std::cout << "Value: " << i << std::endl;
}
此代码编译并提供所需的输出:
价值:8
价值:2
价值:5
Wandbox 上的代码
这使我对我的问题:为什么std::views::take_while一个const谓语,而std::views::filter没有?
THE END
二维码