Extract C++ template parameters

I like Marc Garcia's answer because it shows how to extract the template parameter in a generic way, but I believe his example can be simpler:

#include <type_traits>
#include <iostream>

template<int>
struct MyType {};

template<template <int> typename T, int N>
constexpr int extract(const T<N>&) { return N; }

int main() {
    constexpr MyType<5> myObj;
    std::cout << extract(myObj);
}

Live demo


It's not possible in general to pick arbitrary template parameters.

However, the usual way you do it is this:

template<int N>
struct foo {
    static const int value = N;
};

and for types

template<typename T>
struct foo {
    typedef T type;
};

You can access it then as foo<39>::value or foo<int>::type.

If you have a particular type, you can use partial template specialization:

template<typename>
struct steal_it;

template<std::size_t N>
struct steal_it< std::bitset<N> > {
    static const std::size_t value = N;
};

The same principle is possible for type parameters too, indeed. Now you can pass any bitset to it, like steal_it< std::bitset<16> >::value (note to use size_t, not int!). Because we have no variadic many template paramters yet, we have to limit ourself to a particular parameter count, and repeat the steal_it template specializations for count from 1 up to N. Another difficulty is to scan types that have mixed parameters (types and non-types parameters). This is probably nontrivial to solve.

If you have not the type, but only an object of it, you can use a trick, to still get a value at compile time:

template<typename T>
char (& getN(T const &) )[steal_it<T>::value];  

int main() {
    std::bitset<16> b;
    sizeof getN(b); // assuming you don't know the type, you can use the object
}

The trick is to make the function template auto-deduce the type, and then return a reference to a character array. The function doesn't need to be defined, the only thing needed is its type.


You can easily do this in C++11 using argument deduction and unevaluated contexts (note that demo uses C++14's variable template feature for convenience).

#include <type_traits>
#include <iostream>

template<int>
struct foo {};

template<int arg_N>
struct val {
    static constexpr auto N = arg_N;
};

template<template <int> typename T, int N>
constexpr auto extract(const T<N>&) -> val<N>;

template<typename T>
constexpr auto extract_N = decltype(extract(std::declval<T>()))::N;


int main() {
    std::cout << extract_N<foo<5>>;
}

Live demo