Шаблоны С++ добавляют член класса к классу

51
4

Я хочу создать класс c++, в который я могу добавить элементы типов (int, long, double, string). Я очень новичок в программировании шаблонов в c++.

Я следую этому руководству: https://eli.thegreenplace.net/2014/variadic-templates-in-c/ для вариационных структур данных. Но как я могу ввести тип (int, long и т.д.) И его значение и добавить этот член в мой класс?

Например, если я определяю класс кортежа:

template <class... Ts> struct tuple {};

template <class T, class... Ts>
struct tuple<T, Ts...> : tuple<Ts...> {
tuple(T t, Ts... ts) : tuple<Ts...>(ts...), tail(t) {}

T tail;
};

Затем я хотел бы ввести ввод во время выполнения и:

while(cin>>type) {
cin>>value;
// add type and value to my class
}

И вход может быть int 3 double 3.5 string hello. Мой класс должен быть в этом случае tuple<int, double, std::string> t(3, 3.5, "hello").

Есть ли способ, которым я мог бы достичь этого, используя программирование шаблонов?

спросил(а) 2017-11-27T21:39:00+03:00 2 года, 4 месяца назад
1
Решение
53

Если вы действительно хотите работать со статически типизированным, скажем, std::tuple<int, int, char, int> на основе информации из cin тогда ваш компилятор должен "подготовить" все возможные пути во время компиляции. В зависимости от количества типов N и максимальной длины s существуют различные возможности, т. Число возможностей растет экспоненциально с максимальной длиной s. Для очень малых N и s это может сработать. Поскольку вы, вероятно, предпочитаете другой подход (без статического ввода, скажем, std::tuple<int, int, char, int>), я подготовил пример С++ 17, рассматривающий только типы.

#include <cstdint>
#include <iostream>
#include <tuple>

template<
class F,
class Tuple=std::tuple<>
>
auto tuplify_cin_and_call(
F f,
Tuple tuple=Tuple{}
) {
constexpr std::size_t max_tuple_size = 6;

std::cout << __PRETTY_FUNCTION__ << std::endl;

if constexpr(1 + std::tuple_size<Tuple>::value < max_tuple_size) {
std::cout << "'int'|'char' to append or 'done' to finish: " << std::flush;
std::string input{};
std::cin >> input;

if(input == std::string{"int"}) {
tuplify_cin_and_call(f, std::tuple_cat(tuple, std::tuple<int>{}));
}
else if(input == std::string{"char"}) {
tuplify_cin_and_call(f, std::tuple_cat(tuple, std::tuple<char>{}));
}
else if(input == std::string{"done"}) {
return f(std::move(tuple));
}
else {
std::cout << "ERROR: invalid input" << std::endl;// 'cout' or 'cerr' here?
return tuplify_cin_and_call(f, std::move(tuple));
}
}
else {
std::cout << "max size reached. 'done' to finish: " << std::flush;

std::string input{};
std::cin >> input;

if(input == std::string{"done"}) {
return f(std::move(tuple));
}
else {
std::cout << "ERROR: invalid input" << std::endl;// 'cout' or 'cerr' here?
return tuplify_cin_and_call(f, std::move(tuple));
}
}
}

int main() {
tuplify_cin_and_call(
[] (auto tuple) { std::cout << __PRETTY_FUNCTION__ << std::endl; }
);
return 0;
}

Выход (с включенным входом для клавиатуры):

./main
auto tuplify_cin_and_call(F, Tuple) [with F = main()::<lambda(auto:1)>; Tuple = std::tuple<>]
'int'|'char' to append or 'done' to finish: int
auto tuplify_cin_and_call(F, Tuple) [with F = main()::<lambda(auto:1)>; Tuple = std::tuple<int>]
'int'|'char' to append or 'done' to finish: char
auto tuplify_cin_and_call(F, Tuple) [with F = main()::<lambda(auto:1)>; Tuple = std::tuple<int, char>]
'int'|'char' to append or 'done' to finish: asdf
ERROR: invalid input
auto tuplify_cin_and_call(F, Tuple) [with F = main()::<lambda(auto:1)>; Tuple = std::tuple<int, char>]
'int'|'char' to append or 'done' to finish: char char int
auto tuplify_cin_and_call(F, Tuple) [with F = main()::<lambda(auto:1)>; Tuple = std::tuple<int, char, char>]
'int'|'char' to append or 'done' to finish: auto tuplify_cin_and_call(F, Tuple) [with F = main()::<lambda(auto:1)>; Tuple = std::tuple<int, char, char, char>]
'int'|'char' to append or 'done' to finish: auto tuplify_cin_and_call(F, Tuple) [with F = main()::<lambda(auto:1)>; Tuple = std::tuple<int, char, char, char, int>]
max size reached. 'done' to finish: asdf
ERROR: invalid input
auto tuplify_cin_and_call(F, Tuple) [with F = main()::<lambda(auto:1)>; Tuple = std::tuple<int, char, char, char, int>]
max size reached. 'done' to finish: done
main()::<lambda(auto:1)> [with auto:1 = std::tuple<int, char, char, char, int>]

ответил(а) 2017-11-29T20:54:00+03:00 2 года, 4 месяца назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема