c++c++17variadic-templatesfold-expression

Is it possible to fold only part of the pack with C++17 fold expressions?


I'm trying to figure out how to fold only part of the variadic template pack with C++17 fold expressions. Suppose I'd like to create a compile time "separated string" like "str1_str2_str3_....."

It can be pretty easily done with such a code (just an example):

std::string result;

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

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

Then we can execute it like that

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

As you can see there is a problem with last delimiter. Is there any way I can avoid this problem without runtime checks? One solution I can imagine is to fold only (N - 1) args and concat last one "manually".


Solution

  • You could call ConcatString recursively and use constexpr if to avoid runtime checks

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