constexpr 范围产生与非 constexpr 不同的结果

问题描述 投票:0回答:1

我有以下代码:

#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
一起使用的容器?

c++ constexpr std-ranges c++23
1个回答
0
投票

您可以将瞬态动态分配转换为静态/自动分配,利用

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 来调用它。

© www.soinside.com 2019 - 2024. All rights reserved.