Write the function ToString, which converts its list of different types of arguments to a string value (of type std :: string). The length of the list is arbitrary. For example, for int n = 17; double x = 6.75; ToString (“;”, 25, 3.7, n, x);

where “;” is the separator between elements, we get the string value “25; 3.7; 17; 6.75”;

There is such a solution, but for some reason it cannot work with more than one double variable.

#include <iostream> #include <utility> #include<string> #include <cstring> #include <algorithm> using namespace std; std::string a, c; std::string x_first, c_v, mn; int i = 0,u; char* ch, *ch1, *ch2; template <class T> std::string x_f(T&&t) { i++; if (typeid(t) == typeid(char)) { x_first += t; } else x_first += to_string(t); return x_first; } template <class T> std::string ToString(T&& t) { /*if (typeid(t) == typeid(char)) { char x[] = { t }; a += x; } else */ a = to_string(t); /*a.clear();*/ return a; } template <class T, class... Args> std::string ToString(T&& t, Args&&... args) { a.clear(); if (i == 0) c_v = x_f(t); std::string b = (string)ToString(std::forward<Args>(args)...); if (typeid(t) == typeid(char)) { c = t; } else c = to_string(t); ch1 = (char*)c.c_str(); ch = (char *)b.c_str(); ch2 = (char*)c_v.c_str(); strcat(ch1, ch2); strcat(ch1, ch); //strcat(ch1, to_string(t).c_str()); mn = ch1; return mn; }; int main() { string my_x = ToString(';', 4.5,6.9, 8.4); auto h = [=](string x, string y) { return x.erase(0, 2 * strlen(y.c_str())); }; cout << h(my_x, x_first); return 0; } 

    2 answers 2

    In C ++ 17, this can be done with the help of the fold expression :

     template<typename... T> std::string ToString(const T&... t) { std::stringstream ss; (ss << ... << t); return ss.str(); } 

    In C ++ 11, this is done by expanding the pack in the initializer of the temporary array:

     template<typename... T> std::string ToString(const T&... t) { std::stringstream ss; int temp[] = {((ss << t), 0)...}; (void)temp; return ss.str(); } 

    In the expression (ss << t), 0 the comma operator is used, the left side is the side effect (writing to the stream), the right side is the initializer of the array element.

    Instead of an array, you can use the initialization list:

     (void)std::initializer_list<int>{((ss << t), 0)...}; 

      Well, for example:

       template <typename T> string ToString(T t) { ostrstream os; os << t; return os.str(); } template <typename T, typename ...P> string ToString(T t, P... p) { return [](auto a, auto b) { return ToString(a) + " " + ToString(b); } (t,ToString(p...)); } int main() { std::cout << ToString(2, 2.5, 'x', false, "rrr") << std::endl; } 
      • If the answer has solved the problem, you can tick it off :) - Harry