首页 > 解决方案 > 是否可以使用 C++17 折叠表达式仅折叠包的一部分?

问题描述

我试图弄清楚如何使用 C++17 折叠表达式仅折叠可变参数模板包的一部分。假设我想创建一个编译时“分隔字符串”,例如"str1_str2_str3_....."

使用这样的代码可以很容易地完成(只是一个例子):

std::string result;

template<class... Strings>
ConcatString(Strings&... strs)
{
    (ConcatString(strs), ...);
}

template <class String>
void ConcatString(String& str)
{
     result += str + "_"
}

然后我们可以这样执行

std::string s1 = "s1", s2 = "s2", s3 = "s3";
ConcatString(s1, s2, s3);
// result == "s1_s2_s3_"

如您所见,最后一个分隔符有问题。如果没有运行时检查,有什么办法可以避免这个问题?我可以想象的一种解决方案是仅折叠 (N - 1) 个 args 并“手动”连接最后一个。

标签: c++c++17variadic-templatesfold-expression

解决方案


您可以ConcatString递归调用并使用 constexpr if 以避免运行时检查

template<typename String, typename... Strings>
void ConcatString(String& str, Strings&... strs) {
    if constexpr(sizeof...(strs) == 0) {
        result += str;
    } else {
        result += str + "_";
        ConcatString(strs...);
    }
}

推荐阅读