在编译时何时计算范围::视图?



range-v3 库允许使用views,从而启用对数据的惰性操作。据我所知,只有在编译时计算函数时才有可能进行惰性操作,但要实现编译时计算,代码必须位于可以使用常量表达式的上下文中。

我尝试使用函数ranges::view::repeat_n(0,5)重复一个数字并将其存储为constexpr变量,但编译器错误指出该函数不是constexpr

error: call to non-‘constexpr’ function ‘ranges::repeat_n_view<Val> ranges::views::repeat_n_fn::operator()(Val, std::ptrdiff_t) const requires  copy_constructible<Val> [with Val = int; std::ptrdiff_t = long int]’
16 |     constexpr auto rng_view = ranges::view::repeat_n(0,5);

这是否意味着,观点并不总是恒定的表达?

这是我的主要代码:

#include <iostream>
#include <string>
#include <range/v3/view/empty.hpp>
#include <range/v3/view/repeat_n.hpp>
#include <range/v3/algorithm/for_each.hpp>
#include <range/v3/view/cycle.hpp>
#include <range/v3/view/take.hpp>
using std::cout;
int main() {
constexpr auto rng = ranges::view::empty<int>; //OK
//repeat the number zero five times
constexpr auto rng_view = ranges::view::repeat_n(0,5);//ERROR:Call to non-`constexpr` function
std::cout << rng_view << std::endl;
return 0;
{

是否有可能将所有views存储为constexpr值以确保编译时计算?

只有在

编译时计算函数时才可以使用延迟操作

惰性操作是按需计算结果的操作,而不是在执行似乎计算该结果的表达式时立即计算结果。例如,应用于某个容器的转换视图似乎会立即将转换操作应用于视图的每个元素。但实际上,它仅在您尝试从视图中访问值时应用转换。

此过程与编译时执行无关。

是的,视图并不总是恒定的表达式。一些(例如,如您所发现的空的(可以声明为常量表达式。另一个,repeat_n(),以不允许它成为常量表达式的方式实现的。

但是,这只是回答了您的明确问题。更重要的是,你关于"只有在编译时计算函数时才有可能进行惰性操作"的假设在我看来似乎是错误的,你的结论也随之下降。我不排除我们只是用这个意思不同,所以也许你想澄清一下。

但是,对我来说,惰性求值只需要结果不依赖于任何外部状态,因此在计算某些内容时根本不重要。在上面的情况下,repeat_n()不必生成值序列,直到它们被实际使用。这是一个不好的例子,因为任何健全的实现都不会生成超过一个值,但这无关紧要。在惰性求值中没有隐含的要求,强制它成为一个常量表达式,也没有什么可以阻止它成为一个。

最新更新