为什么Ranges库中的std::views::take_while需要const谓词?

TL; DR:我玩弄范围和相应的一系列的适配器从范围图书馆。范围适配器std::views::take_whilestd::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没有?

以上是为什么Ranges库中的std::views::take_while需要const谓词?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>