如何通过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)); }
疑问
- 这两者是否是同一功能的不同实现?
- 两者是否有各自更适用的场景?
- 是否存在不依赖第三方库的实现方式?
内容的提问来源于stack exchange,提问作者Torsten Knodt
相关产品推荐
相关产品推荐

