I have a member function that is templated with a variadic template. The member function wants to push to a container somewhere some information about the types in the variadic template, such as typeid(T)
and sizeof(T)
.
The member function should also take in a variable amount of parameters, with each parameter's type being what is specified in the variadic template. Any parameter not explicitly defined should default to a default construction of the type.
Basically this, but bar is somehow a variadic template and that code repeats for all of the types in the variadic template.
class foo {
private:
std::unordered_map<std::type_index, std::size_t> typeinfo;
public:
template<typename T>
void bar(T myType = T()) {
typeinfo.insert({ typeid(T), sizeof(T) });
// do stuff with myType ...
}
};
foo myfoo;
myfoo.bar<int, double>(); // myType<int> = 0, myType<double> = 0.0;
myfoo.bar<char, float>('a'); // myType<char> = 'a', myType<float> = 0.0f;
myfoo.bar<double, char>(32.4, 'b'); // myType<double> = 32.4, myType<char> = 'b'
Parameter pack cannot have default argument
so
template<typename... Ts>
void bar(Ts... = Ts()...) // ill-formed
What you can do is using 2 parameter-packs
class foo {
private:
std::unordered_map<std::type_index, std::size_t> typeinfo;
public:
// Us... is non deducible
template<typename... Us, typename... Ts>
void bar(Ts... /*args*/) {
(typeinfo.insert({ typeid(Us), sizeof(Us) }), ...);
// You might have to check that Ts... start Us...
// use end of Us... for args...
}
};
void test()
{
foo myfoo;
myfoo.bar<int, double>(); // Us=[int, double], Ts=[]
myfoo.bar<char, float>('a'); // Us =[char, float], Ts = [char];
myfoo.bar<double, char>(32.4, 'b'); // Us=[double, char], Ts=[double, int]
myfoo.bar<char>(4.2f); // Us =[char], Ts = [float] !!!
}
To create a tuple with initial part from Us
, and remaining defaulted, you might do
template <typename T, std::size_t I, typename Tuple>
T get_or_default(Tuple&& tuple)
{
if constexpr (I < std::tuple_size_v<std::decay_t<Tuple>>) {
return std::get<I>(std::forward<Tuple>(tuple));
} else {
return T{};
}
}
template<typename... Ts, std::size_t... Is, typename Tuple>
std::tuple<Ts...>
make_partial_tuple_impl(std::index_sequence<Is...>, Tuple&& tuple)
{
return {get_or_default<Ts, Is>(std::forward<Tuple>(tuple))...};
}
template<typename... Ts, typename... Us>
std::tuple<Ts...> make_partial_tuple(Us&&... args)
{
return make_partial_tuple_impl<Ts...>(
std::make_index_sequence<sizeof...(Ts)>{},
std::forward_as_tuple(std::forward<Us>(args)...));
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.