Страницы

Поиск по вопросам

пятница, 5 апреля 2019 г.

Написать функцию ToString, которая список своих разнотипных аргументов преобразует в строковой значение (std::string)

Написать функцию ToString, которая список своих разнотипных аргументов преобразует в строковой значение (типа std::string). Длина списка произвольная. Например, для int n = 17; double x = 6.75; ToString(“;”, 25, 3.7, n, x) ;
где “;” – разделитель между элементами, получим строковое значение “25;3.7;17;6.75”;
Есть такое решение, но оно почему-то не может работать больше чем с одной переменной типа double.
#include #include #include #include #include using namespace std; std::string a, c; std::string x_first, c_v, mn; int i = 0,u; char* ch, *ch1, *ch2; template 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 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 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)...); 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; }


Ответ

В C++17 это можно будет сделать при помощи fold expression (выражения свертки):
template std::string ToString(const T&... t) { std::stringstream ss; (ss << ... << t); return ss.str(); }
В C++11 это делается через разворачивание пака в инициализаторе временного массива:
template std::string ToString(const T&... t) { std::stringstream ss;
int temp[] = {((ss << t), 0)...}; (void)temp;
return ss.str(); }
В выражении (ss << t), 0 используется оператор запятая, левая часть это сайд-эффект (запись в поток), правая часть - инициализатор элемента массива.
Вместо массива можно использовать список инициализации:
(void)std::initializer_list{((ss << t), 0)...};

Комментариев нет:

Отправить комментарий