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

使用折叠表达式拼接string_view报错,请求排查问题原因

问题:折叠表达式拼接string_view函数编译失败原因

我希望实现一个利用折叠表达式拼接string_view的函数,但编写的代码无法正常运行,请问问题出在哪里?

#include <string_view>
#include <string>

using namespace std;

template<typename Allocator, typename Char, typename Traits>
auto sv_concat( basic_string_view<Char, Traits> svs ... )
{
    basic_string<Char, Traits, Allocator> str;
    str.reserve( (svs.length() + ...) );
    ((str += svs), ...);
    return str;
}

clang++ 18的报错信息翻译如下:

test.cpp:14:31: 错误:折叠展开中未包含任何未展开的参数包
   14 |         str.reserve( (svs.length() + ...) );
      |                       ~~~~~~~~~~~~   ^
test.cpp:15:17: 错误:折叠展开中未包含任何未展开的参数包
   15 |         ((str += svs), ...);
      |          ~~~~~~~~~~~~  ^

问题原因

你代码里的basic_string_view<Char, Traits> svs ...是C风格可变参数(即...用于函数参数的可变参数列表),而非C++的模板参数包。折叠表达式只能用于模板参数包,无法作用于C风格可变参数,因此编译器报错“未包含未展开的参数包”。

C风格可变参数是C语言遗留特性,用于处理不确定数量的同类型参数,但它不属于模板参数包范畴,折叠表达式无法识别和展开它。

修正方案

需要将函数参数改为模板参数包,并约束所有参数都是basic_string_view<Char, Traits>类型,同时可以给Allocator设置默认值以简化调用:

#include <string_view>
#include <string>
#include <concepts>

using namespace std;

template<typename Char, typename Traits = char_traits<Char>, typename Allocator = allocator<Char>, typename... SVs>
requires (is_same_v<SVs, basic_string_view<Char, Traits>> && ...)
auto sv_concat(SVs... svs)
{
    basic_string<Char, Traits, Allocator> str;
    str.reserve( (svs.length() + ...) );
    ((str += svs), ...);
    return str;
}

关键修改点:

  • 新增模板参数包typename... SVs,用于接收所有传入的string_view参数
  • 使用requires约束确保所有SVs参数都是basic_string_view<Char, Traits>类型,避免传入不兼容类型
  • 给Traits和Allocator设置默认值,调用时无需手动指定这些参数(比如直接sv_concat(sv1, sv2, sv3)即可)
  • 函数参数改为SVs... svs,这才是C++模板参数包,能被折叠表达式正确展开

如果你的编译器不支持C++20概念,可以改用static_assert做编译期检查:

template<typename Char, typename Traits = char_traits<Char>, typename Allocator = allocator<Char>, typename... SVs>
auto sv_concat(SVs... svs)
{
    static_assert( (is_same_v<SVs, basic_string_view<Char, Traits>> && ...), "All arguments must be basic_string_view<Char, Traits>" );
    basic_string<Char, Traits, Allocator> str;
    str.reserve( (svs.length() + ...) );
    ((str += svs), ...);
    return str;
}

内容的提问来源于stack exchange,提问作者Edison von Myosotis

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 10:23:15