Reputation: 739
The range-v3 library allows the use of views
, which enable lazy operations on data. From what I know, lazy operations are only possible when a function is evaluated at compile time, but to achieve a compile time calculation, the code must be in a context where a constant expression is possible.
I tried out to repeat a number by using the function ranges::view::repeat_n(0,5)
and store it as a constexpr
variable, but the compiler error points out that the function is not a 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);
Does that mean, that views aren't always constant expression ?
Here my main code:
#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;
{
Is there any possibility to store all views
as constexpr
values to ensure a compile time calculation?
Upvotes: 1
Views: 915
Reputation: 473447
lazy operations are only possible when a function is evaluated at compile time
Lazy operations are operations which compute a result on-demand rather than immediately upon executing the expression which appears to compute that result. For example, a transform view applied to some container appears to immediately apply the transform operation to every element of the view. But in reality, it only applies the transformation when you attempt to access the value from the view.
This process has nothing to do specifically with compile-time execution.
Upvotes: 3
Reputation: 17415
Right, views are not always constant expressions. Some (like e.g. the empty one, as you discovered) can be declared as constant expressions. The other one, repeat_n()
, is implemented in a way that doesn't allow it to be a constant expression.
However, that just answers your explicit question. More important is that your assumption that "lazy operations are only possible when a function is evaluated at compile time" seems wrong to me and with that your conclusions tumble as well. I don't exclude that we just mean different things with this, so maybe you want to clarify.
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.
Upvotes: 3