Доброго времени суток, уважаемые.
У меня следующий вопрос:
Пусть есть шаблонный класс вот такого вида:
template <class... Ts> class MyClass
{
public:
using TupleT = std::tuple<Ts...>;
...
private:
TupleT m_tuple;
};
и есть шаблонный класс
template <size_t I, class TupleT> WrapperT { ... };
Хочется сделать следующее: изменить тип m_tuple внутри MyClass с указанного выше на тип TupleWrappedT таким образом, что WrapperT будет выбирать по индексу элемент из TupleT и оборачивать его в себя. Вопрос, собственно, в том, как такой тип определить. Я придумал только
template <size_t... Is> using TupleWrappedT = std::tuple<WrapperT<Is, TupleT>...>;
возможно ли обойтись без приставки template <size_t... Is>? С учетом того, что элементы Is должны быть последовательны в диапазоне от 0 до sizeof...(Ts), а значит, известны на этапе компиляции.
Заранее благодарю за ответ.
Держите :)
#include <tuple>
template <size_t I, class TupleT> struct WrapperT {};
template <class Tuple, size_t... Is>
static std::tuple<WrapperT<Is, Tuple>...> wrap_impl(std::index_sequence<Is...>);
template <class Tuple>
static auto wrap() -> decltype(wrap_impl<Tuple>(std::make_index_sequence<std::tuple_size<Tuple>::value>()));
template <class... Ts> class MyClass
{
public:
using TupleT = std::tuple<Ts...>;
using TupleWrappedT = decltype(wrap<TupleT>());
private:
TupleT m_tuple;
};
int main() {
static_assert(std::is_same<MyClass<int, float>::TupleT, std::tuple<int, float>>::value, "!");
static_assert(std::is_same<MyClass<int, float>::TupleWrappedT, std::tuple<WrapperT<0, std::tuple<int, float>>, WrapperT<1, std::tuple<int, float>>>>::value, "!");
return 0;
}
Возможно я чего-то не понял, но разве std::tuple_element и std::get не решают задачу? Пример:
template <size_t I, class TupleT> class WrapperT
{
using Element = typename std::tuple_element<I, TupleT>::type;
Element mElement;
public: WrapperT(const TupleT& tuple)
: mElement{std::get<I>(tuple)}
{
}
};
Продвижение своими сайтами как стратегия роста и независимости