You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过std::ranges::views::transform以最简方式应用转换构造函数?

关于constexpr下split结果转string_view的封装问题

我正在开发一个constexpr解析器,用于解析文本文件并生成对象表示。当前使用G++ 14.1.0,也可切换编译器(目前认为G对新版C的支持优于Clang)。

我大量使用std::ranges::views::split,随后通过std::ranges::views::transform将结果转换为std::string_view,示例代码如下:

#include <ranges>
#include <string_view>

using namespace std::literals::string_view_literals;

int main() {
    constexpr std::string_view input = "A,B B,C C,D C,E D,F"sv;
    constexpr auto working =
        input | std::ranges::views::split(","sv) |
        std::ranges::views::transform(
            [](const auto input) { return std::string_view(input); });
}

由于这段转换代码重复率高且可读性差,我尝试将转换构造函数调用或整个转换逻辑封装到constexpr函数中,但多次尝试均失败:

  • 直接传入std::string_view::string_view,报错:'string_view' is not a member of 'std::string_view' {aka 'std::basic_string_view<char>'}
  • 直接传入std::string_view,报错:expected primary-expression before ')'
  • 定义constexpr函数to_string_view,调用时编译器无法推导模板参数_Fp,报错匹配失败

之后我通过std::bind_back结合lambda实现了转换,但失去了更易读的|管道语法,且lambda写法不够简洁,代码如下:

#include <concepts>
#include <functional>
#include <ranges>
#include <string_view>

using namespace std::literals::string_view_literals;

static auto constexpr to_string_transform_view = std::bind_back(
    std::ranges::views::transform, [](const auto input)
        requires(std::constructible_from<std::string_view, decltype(input)>)
    { return std::string_view(input); });

int main() {
    constexpr std::string_view input = "A,B B,C C,D C,E D,F"sv;
    auto constexpr test =
        to_string_transform_view(input | std::ranges::views::split(","sv));
}

Boost的两种实现方案

方案1:使用boost::value_factory

#include <concepts>
#include <functional>
#include <ranges>
#include <string_view>

#include <boost/functional/value_factory.hpp>

using namespace std::literals::string_view_literals;

static auto constexpr to_string_transform_view = std::bind_back(
    std::ranges::views::transform, boost::value_factory<std::string_view>());

int main() {
    constexpr std::string_view input = "A,B B,C C,D C,E D,F"sv;
    auto constexpr test =
        to_string_transform_view(input | std::ranges::views::split(","sv));
}

方案2:使用boost::lambda::constructor

#include <concepts>
#include <functional>
#include <ranges>
#include <string_view>

#include <boost/lambda/construct.hpp>

using namespace std::literals::string_view_literals;

static auto constexpr to_string_transform_view = std::bind_back(
    std::ranges::views::transform, boost::lambda::constructor<std::string_view>());

int main() {
    constexpr std::string_view input = "A,B B,C C,D C,E D,F"sv;
    auto constexpr test =
        to_string_transform_view(input | std::ranges::views::split(","sv));
}

疑问

  1. 这两者是否是同一功能的不同实现?
  2. 两者是否有各自更适用的场景?
  3. 是否存在不依赖第三方库的实现方式?

内容的提问来源于stack exchange,提问作者Torsten Knodt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 20:43:17