Find out how this variadic templated function works

萝らか妹 提交于 2019-12-12 17:15:56

问题


In this answer I have seen some C++11 code, that I don't really understand (but I would like to).

There, a variadic template function is defined, that (maybe?) takes all arguments passed and inserts them into a std::ostringstream.

This is the function (see the complete working example at the linked answer):

template<typename T, typename... Ts>
std::string CreateString(T const& t, Ts const&... ts)
{
    using expand = char[];

    std::ostringstream oss;
    oss << std::boolalpha << t;
    (void)expand{'\0', (oss << ts, '\0')...};
    return oss.str();
}

When I had to guess, I'd say, a character array is created and initialized with \0-bytes, and the insertion of the function's arguments into the stream happens as a side effect of the initialization (part of that comma expression). In the end, the array contains as many nulls as items were inserted into the stream. It's casted to void in order to avoid a compiler warning (unused variable). Similar to this:

char arr[] = {'\0', (oss << t1, '\0'), (oss << t2, '\0'), ..., (oss << tn, '\0')};

Is my attempt to describe this function's workings accurate? Can someone explain what design decision might be relevant here, and why is it beneficial to implement it this way (the alternative would be compile-time recursion, I guess)?


回答1:


After receiving some helpful hints in the question's comment section I could figure out some of the points:

  • The feature being used is called pack expansion. It works exactly as described in the OP: a temporary array is initialized with the side effect of stream insertion. A detailed description of the feature can be found here:
    • http://en.cppreference.com/w/cpp/language/parameter_pack
  • This is a work-around that is necessary to avoid the recursion approach, which would be less efficient. In C++17 this work-around is no longer needed, because of the then introduced fold expressions:
    • http://en.cppreference.com/w/cpp/language/fold
    • See also this question's answers: Variadic template pack expansion
  • The first array element is initialized \0 to avoid the program being ill-formed if the function was called with only one argument. Else, the array object would be created empty, with an incomplete type (array of unknown bounds), which is illegal. For further reading:
    • http://en.cppreference.com/w/cpp/language/array


来源:https://stackoverflow.com/questions/35232729/find-out-how-this-variadic-templated-function-works

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!