Do you want it to work for containers or fully generic solution? STL containers have special members documenting their "kinds". Vector has ::value_type
, map has key_type
and mapped_type
.
The following might be able to extra generic template arguments:
#include <tuple>
template <typename T> struct parameter_type_impl;
template <template <class...> class T, typename... Args>
struct parameter_type_impl<T<Args...>> {
using type = std::tuple<Args...>;
};
// Using the sane zero-based indexing.
template <typename T, std::size_t I = 0>
using parameter_type =
std::tuple_element<I, typename parameter_type_impl<T>::type>;
template <typename T, std::size_t I = 0>
using parameter_type_t = typename parameter_type<T, I>::type;
#include <map>
#include <vector>
int main() {
using v1 = parameter_type_t<std::vector<int>>;
static_assert(std::is_same_v<v1, int>);
using v2 = parameter_type_t<std::map<int, float>>;
static_assert(std::is_same_v<v2, int>);
using v3 = parameter_type_t<std::map<int, float>, 1>;
static_assert(std::is_same_v<v3, float>);
}
I am not quite sure whether there are any edge cases which won't match the variadic specialization so your mileage might vary.