首页 > 解决方案 > 范围::views 何时在编译时计算?

问题描述

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;
{

是否有可能将所有内容存储viewsconstexpr值以确保编译时间计算?

标签: c++c++20range-v3

解决方案


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

但是,这只是回答了您的明确问题。更重要的是,您认为“只有在编译时评估函数时才可能进行惰性操作”的假设对我来说似乎是错误的,并且您的结论也会失败。我不排除我们只是意味着不同的东西,所以也许你想澄清一下。

However, to me, lazy evaluation only requires that the result doesn't depend on any external state, so that it simply doesn't matter when something is computed. In above case, repeat_n() doesn't have to generate the sequence of values until they are actually used. This is a bad example, because any sane implementation would never generate more than a single value, but that's beside the point. There is no implied requirement in lazy evaluation that forces this to be a constant expression and also nothing that prevents it from being one.


推荐阅读