Распаковка variadic templates

231
25 мая 2022, 06:00

У меня есть шаблонная функция, которая принимает на вход параметры Args... args, я бы хотела перегнать все аргументы в вектор строк vector<string> arg или можно к другой структуре, к которой удобно обращаться по индексу аргумента и которая содержит строковое представление каждого аргумента.

Как это лучше сделать ?

Answer 1

Смотрите на код ниже

#include <iostream>
#include <vector>
#include <string>
// для старых добрых сишных строк
std::string to_str(const char* c)
{
    return std::string(c);
}
// самый простой способ преобразовать число в строку
std::string to_str(double x) {
    return std::to_string(x);
}
// для целого просто вызываем to_string
std::string to_str(int x) {
    return std::to_string(x);
}
// покажем, что даже вектор можно будет обрабатывать
template <typename T>
std::string to_str(const std::vector<T>& v)
{
    std::string s = "[ ";
    for (const T& el : v) {
        s += to_str(el) + " ";
    }
    s += ']';
    return s;
}
/* если у Вас будет какой то свой тип (своя чудо строка MyCoolString), то для нее нужно
просто определить функцию вида
std::string to_str(const MyCoolString& s)
{
   return "строковое представление";
}
И не обязательно в этом же файле, главное, что бы компилятор мог найти.
*/
//собственно магическая функция, которая делает всю магию
// для каждого аргумента она вызывает to_str, которая должна уметь преобразовать
// в строку.
template <typename...Args>
std::vector<std::string> to_vec(Args... params)
{
    return std::vector<std::string> {to_str(params)...};
}
// для удобства вывода
std::ostream& operator<<(std::ostream& os, const std::vector<std::string>& s)
{
    for (const auto& s : s) {
        os << s << " ";
    }
    return os;
}
// пример вызова
int main()
{
    std::cout << to_vec(1,2, 1.2f, "a", std::vector<int>{1,2,3});
}

P.S. Можно было не городить город с to_str, а использовать везде std::to_string, но почему то для const char* в стандартной поставке там нет перегрузки, а также иногда хочется своих классов. Да, можно это все впихнуть вот так

namespace std {
  string to_string(const char* s) { return string(s); }
}

но засорение std - не лучшая идея.

READ ALSO
Не могу понять простейший алгоритм

Не могу понять простейший алгоритм

Нужно посчитать XOR-ы всех чисел на заданном отрезкеОперация xor мне знакома, но я не знаю как посчитать xor-ы всех чисел

222
Перегрузка операции

Перегрузка операции

Началась новая тема и я никак не могу понять, что требуется и как это реализовать на практикеЕсли кто-нибудь сможет разъяснить, показать пример(с...

171
Создание прозрачного окна с поддержкой непрозрачных / полупрозрачных объектов

Создание прозрачного окна с поддержкой непрозрачных / полупрозрачных объектов

Необходимо сделать так, чтобы на прозрачном окне можно было создавать объекты любой прозрачности и чтобы эта прозрачность не зависела от окна

246