tobi303 tobi303 - 3 years ago 96
C++ Question

how to get template parameter of a template template parameter?

Assume

std::vector
didnt have a
value_type
. Is is possible to write a template to deduce the
value_type
? Or more general, given a
T<X>
, how can I deduce
X
?

A very naive..

template <template <typename X> T>
void test(T<X> t) {
X x;
}


will probably make anybody who knows a bit about templates laugh at my foolish attempt and when instantiated like this:

int main() {
std::vector<int> x;
test(x);
}


create the following errors:

error: expected ‘class’ before ‘T’
template < template<typename X> T>
^
error: ‘X’ was not declared in this scope
void test(T<X> u) {
^
error: template argument 1 is invalid
void test(T<X> u) {
^
In function ‘void test(int)’:
error: ‘X’ was not declared in this scope
X x;
^
error: expected ‘;’ before ‘x’
X x;
^
In function ‘int main()’:
error: no matching function for call to ‘test(std::vector<int>&)’
test(x);
^
note: candidate is:
note: template<template<class X> class T> void test(int)
void test(T<X> u) {
^
note: template argument deduction/substitution failed:
note: cannot convert ‘x’ (type ‘std::vector<int>’) to type ‘int’


EDIT: the first one is easy to fix, but fixing it wont affect the others...

PS: I think I have a small misunderstanding, as
std::vector<int>
isnt a template, but a concrete type. However, still I would like to know if there is a way to get the
int
from a
someTemplate<int>
with some template magic.

Answer Source

You can create a traits to extract those parameter:

template <typename T> struct first_param;

template <template <typename, typename...> class C, typename T, typename ...Ts>
struct first_param<C<T, Ts...>>
{
    using type = T;
};

For pre C++11, you have to handle number of parameters until acceptable values:

template <typename T> struct first_param;

template <template <typename> class C, typename T>
struct first_param<C<T>>
{
    typedef T type;
};

template <template <typename, typename> class C, typename T, typename T2>
struct first_param<C<T, T2>>
{
    typedef T type;
};

template <template <typename, typename, typename> class C,
          typename T, typename T2, typename T3>
struct first_param<C<T, T2, T3>>
{
    typedef T type;
};

// ...
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download