в структуру std::tuple?
В случае вектора я могу захватить переданные значения в фигурных скобках через std::initializer_list
#include <iostream>
#include <vector>
template<typename T>
struct Frame{
std::vector<T> children;
};
template<typename T> Frame(std::initializer_list<T>) -> Frame<T>;
int main(){
auto frame = Frame{.children = {111, 112, 113}};
std::cout << frame.children[0];
}
Здесь я указал для дедакт-гайда Frame(std::initializer_list<T>) -> Frame<T> и теперь могу инициализировать как Frame{.children = {1, 2, 3}}
Но теперь я хочу поменять std::vector на std::tuple
#include <iostream>
#include <tuple>
template<typename... T>
struct Frame{
std::tuple<T...> children;
};
template<typename...T> Frame(???) -> Frame<T...>;
int main(){
auto frame = Frame{.children = {123, 123.123, "123"}};
std::cout << std::get<0>(frame.children);
}
и не могу понять что мне нужно написать в конструкторе дедакт-гайда чтобы захватить список из фигурных скобок (в выражении Frame{.children = {123, 123.123, "123"}} где могут быть разные типы
#include <iostream> #include <tuple> template<typename... Ts> struct Frame { std::tuple<Ts...> children; // Конструктор, принимающий std::tuple Frame(std::tuple<Ts...> t) : children(t) {} }; // Deduction guide template<typename... Ts> Frame(std::tuple<Ts...>) -> Frame<Ts...>; int main() { // Используем std::make_tuple для инициализации auto frame = Frame(std::make_tuple(123, 123.123, "123")); // Выводим первый элемент std::cout << std::get<0>(frame.children) << std::endl; }
Я бы сказал что воняет
А без make_tuple на колл-сайте возможно? Я хочу просто как Frame{.children = {123, 123.123, "123"}}
и тут у гпт 2 ошибки
нельзя так, вывод типов ради вывода типов, запрещено стандартом
Смотри что я хочу. Сейчас есть возможность через designated-initialzers вызвать конструктор для вложенного в структуру типа Children передавая в фигурных скобках разные типы #include <iostream> #include <vector> struct Children { Children(auto...arg){ ([](auto arg){ std::cout << arg << "\n"; }(arg), ...); } }; struct Frame { Children children; int left; int top; }; int main(){ auto frame = new Frame{ //вместо .children = Children{123, 123.123, "123"} .children = {123, 123.123, "123"}, .left = 10, .top = 20 }; } Но поскольку Children не является шаблонным то я не могу сохранить полученные аргументы (например в std::tuple) То есть мне нужно сделать шаблонной структуру Children и также ее родительскую структуру Frame и написать deduction-guide для проброса типов из конструктора Frame в конструктор Children Пока у меня получился рабочий пример но только с одним типом (где в deduction guide я захватывю фигурные скобки как std::initalizer_list<T>) #include <iostream> #include <vector> template<typename T> struct Frame{ std::vector<T> children; int left; int top; }; template<typename T> Frame(std::initializer_list<T>, auto...args) -> Frame<T>; int main(){ auto frame = new Frame{ .children = {1, 2, 3}, .left = 10, .top = 20 }; } Но попытка захватить фигурные скобки с разными типами (чтобы записать в std::tuple) уже не работает #include <iostream> #include <tuple> template<typename... T> struct Frame{ std::tuple<T...> children; int left; int top; }; template<typename... T> Frame(std::tuple<T...>, auto...args) -> Frame<T...>; int main(){ auto frame = new Frame{ .children = {123, 123.123, "123"}, .left = 10, .top = 20 }; } Я так понимаю проблема в том что указывая в deduction-guide Frame(std::tuple<T...>) -> Frame<T...> компилятор требует от меня явно передать std::tuple при инициализации auto frame = new Frame{ .children = std::tuple{123, 123.123, "123"}, .left = 10, .top = 20 }; но это некрасиво, я хочу каким-то образом захватить разные типы в фигурных скобках как в первом примере когда я могу вызвать конструктор Children без явного создания инстанса int main(){ auto frame = new Frame{ //вместо .children = Children{123, 123.123, "123"} .children = {123, 123.123, "123"}, .left = 10, .top = 20 }; } В С++ это вообще возможно сделать? Если нет то здесь явно напрашивается пропозал для добавления в стандартную библиотеку std::initializer_list но не для одного а для множества разных типов как std::initializer_list<T1, T2, T3, ...>
сделай уже any_child
ты имеешь ввиду стирание типа? Я этого и пытаюсь избежать. Я сейчас изучаю какие есть возможности построить в С++ статическое дерево объектов (из нод разных типов)
Компилировать ты это будешь годами, даже если сделаешь
Обсуждают сегодня