I have the following code:
#include <ranges>
#include <algorithm>
auto func(const char* Str) {
return std::string_view(Str)
| std::views::split(',')
| std::views::transform([](auto inp) { return inp.data(); })
| std::ranges::to<std::vector<const char *>>();
}
Note I know that the result of func(test)
, where test = "a,b"
would be to pointers pointing into test
and thus printing them would result in ["a,b", "b"]
but I am only concerned with the beginning of the string anyways.
I tried to make this function consteval
, as i saw that all the std::ranges
functions are allconstexpr
. This was my attempt:
template<const char * Str>
consteval auto func() {
return std::string_view(Str)
| std::views::split(',')
| std::views::transform([](auto inp) { return inp.data(); })
| std::ranges::to<std::vector<const char *>>();
}
But I get the error (See demo)
error: call to consteval function 'func<test>' is not a constant expression
note: pointer to subobject of heap-allocated object is not a constant expression
where test
is a "string" of type static constexpr char[]
. I know that this error stems from std::vector
allocating memory, but I thought std::vector
supports constexpr
. Though maybe it is the problem of std::ranges::to
which does not treat the destination container type as constexpr
.
I have also tried to use std::ranges::to<std::array>
but to
did not support that either. Is there another container which supports random access and constexpr
which works with std::ranges::to
?
You can turn the transient dynamic allocations into a static/automatic allocation, taking advantage of the fact that vector_returning_function().size()
can be a constant expression (because the vector dies and returns its memory):
https://godbolt.org/z/MKser4ses
consteval auto vector_to_array(auto f) {
static constexpr std::size_t size = f().size();
return [f]<std::size_t... I>(std::index_sequence<I...>) mutable {
return std::array<std::ranges::range_value_t<decltype(f())>, size>{{ f()[I]... }};
}(std::make_index_sequence<size>{});
}
You call it with a captureless lambda that returns the vector instead.