我有以下代码:
#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 *>>();
}
注意我知道
func(test)
的结果,其中test = "a,b"
将是指向test
的指针,因此打印它们将导致["a,b", "b"]
,但我只关心字符串的开头。
我尝试制作这个功能
consteval
,因为我看到所有std::ranges
功能都是constexpr
。这是我的尝试:
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 *>>();
}
但是我收到错误(参见演示)
错误:调用 consteval 函数“func
”不是常量表达式
注意:指向堆分配对象的子对象的指针不是常量表达式
其中
test
是 static constexpr char[]
类型的“字符串”。我知道这个错误源于std::vector
分配内存,但我认为std::vector
支持constexpr
。虽然可能是 std::ranges::to
的问题,它没有将目标容器类型视为 constexpr
。
我也尝试过使用
std::ranges::to<std::array>
,但to
也不支持。是否有另一个支持随机访问且 constexpr
与 std::ranges::to
一起使用的容器?
您可以将瞬态动态分配转换为静态/自动分配,利用
vector_returning_function().size()
可以是常量表达式的事实(因为向量死亡并返回其内存):
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>{});
}
您可以使用返回向量的无捕获 lambda 来调用它。