Although I'm doubtful, I'm curious as to whether it's possible to extract primitive-type template parameters from an existing type, perhaps using RTTI.
For example:
typedef std::bitset<16> WordSet;
Would it be possible to extract the number 16 in the above code without hard-coding it elsewhere? Compiler specific implementations are welcome, though I'm particularly interested in g++
.
Template classes and functions can make use of another kind of template parameter known as a non-type parameter. A template non-type parameter is a template parameter where the type of the parameter is predefined and is substituted for a constexpr value passed in as an argument.
Template parameters may have default arguments. The set of default template arguments accumulates over all declarations of a given template.
In UML models, template parameters are formal parameters that once bound to actual values, called template arguments, make templates usable model elements. You can use template parameters to create general definitions of particular types of template.
Explanation of the code: In the above program, the Test constructor has two arguments of generic type. The type of arguments is mentioned inside angle brackets < > while creating objects.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With