Страницы

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

воскресенье, 2 февраля 2020 г.

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

#cpp


Написать функцию 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;
 }

    


Ответы

Ответ 1



В 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)...};

Ответ 2



Ну, например: template string ToString(T t) { ostrstream os; os << t; return os.str(); } template 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; }

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

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