Реализация обертки типизированного кортежа
Как может выглядеть реализация, которая охватывает, например,
std::tuple
как статический список типа/значения плюс тип (не содержащийся в кортеже) для ссылки на какого-либо владельца/посетителя.
Я хочу создать экземпляр как
constexpr auto data = data_of<a>(1, 2.0);
Фон
Идея состоит в том, чтобы использовать
data_of<T>(...)
тип структуры для передачи списка пар тип/данные в массовую функцию, подобную этой.
template <typename... _Ts>
static constexpr void do_bulk_stuff(_Ts&&... _Vs)
{
// crazy stuff happens here
}
// call it like
do_bulk_stuff
(
data_of<a>(1, 2.0),
data_of<b>(3),
data_of<c>(4.0, 5, 6),
// ...
);
Попытка 1
До сих пор я столкнулся с наивной (не работающей) попыткой реализации, например
template <typename T, typename... Ts>
struct data_of {
using type = T;
using data_t = std::tuple<Ts...>;
data_t data;
constexpr data_of(Ts&&... Vs)
: data(Vs...)
{}
};
Цель
Моя цель добиться такого результата
data_of<a>
пример псевдокода экземпляра
{
// meta
type = a;
data_t = std::tuple<int,double>;
// runtime
data = [1, 2.0];
}
1 ответ
Проблема, присущая вашей попытке, заключается в том, что вывод аргумента шаблона класса просто не похож на аналог функции. Вывода не будет, если явно указан какой-либо из аргументов шаблона класса. Вы терпите неудачу, потому что замыкающий пакет всегда указывается (путем пропуска) как пустой.
Решение — переложить нагрузку на механизм, позволяющий указывать только часть аргументов: шаблоны функций.
template <typename T, typename... Ts>
struct data_of_t {
using type = T;
using data_t = std::tuple<Ts...>;
data_t data;
constexpr data_of_t(Ts&&... vs)
: data(std::forward<Ts>(vs)...)
{}
};
template<typename T, typename... Ts>
constexpr auto data_of(Ts&&... vs) {
return data_of_t<T, Ts...>(std::forward<Ts>(vs)...);
}
Теперь тип выражения
data_of<a>(1, 2.0)
имеет те же «мета» свойства, которые вам нужны.