Reputation: 2355
Is it possible to wrap or change the type of variadic template arguments? E.g. when giving template arguments int, float, double
to return a std::tuple<const int*, const float*, const double*>
or a std::tuple<std::unique_ptr<int>, std::unique_ptr<float>, std::unique_ptr<double>>
?
I'm asking because I've got this piece of non-variadic code:
#pragma once
#include <Variant>
namespace fw::variant {
/*- Returns a variant with a pointer to the value of vFrom.*/
template<typename Arg1, typename Arg2>
std::variant<Arg1*, Arg2*> GetPointerVariant(std::variant<Arg1, Arg2>& vFrom) {
if (std::holds_alternative<Arg1>(vFrom)) {
return &std::get<Arg1>(vFrom);
}
return &std::get<Arg2>(vFrom);
}
/*- Returns a variant with a pointer to the value of vFrom.*/
template<typename Arg1, typename Arg2>
const std::variant<const std::remove_const_t<Arg1>*, const std::remove_const_t<Arg2>*> GetPointerVariant(const std::variant<Arg1, Arg2>& vFrom) {
if (std::holds_alternative<Arg1>(vFrom)) {
return &std::get<Arg1>(vFrom);
}
return &std::get<Arg2>(vFrom);
}
}
which I would like to make variadic.
Upvotes: 1
Views: 109
Reputation: 42776
Yes, you can define a type trait like this:
template <
template <typename...> typename V,
template <typename> typename Op,
typename... Args
>
struct modify {
using type = V<typename Op<Args>::type...>;
};
where V
is a template template arguments that accommodate variadic template arguments such as std:variant
or std::tuple
,
and Op
is what you want to modify the variadic template arguments Args...
.
Then your just need define your own Op
s:
template <typename T>
struct Op1 { using type = const T*; };
template <typename T>
struct Op2 { using type = std::unique_ptr<T>; };
and it will works:
static_assert(std::is_same_v<
std::tuple<const int*, const float*, const double*>,
modify<std::tuple, Op1, int, float, double>::type
>);
static_assert(std::is_same_v<
std::variant<std::unique_ptr<int>, std::unique_ptr<float>, std::unique_ptr<double>>,
modify<std::variant, Op2, int, float, double>::type
>);
Upvotes: 3