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
You call it with a captureless lambda that returns the vector instead.