Insert a transformed integer_sequence into a variadic template argument? - c++

How do you insert a transformed integer_sequence (or similar since I am targeting C++11) into a variadic template argument?
For example I have a class that represents a set of bit-wise flags (shown below). It is made using a nested-class because you cannot have two variadic template arguments for the same class. It would be used like typedef Flags<unsigned char, FLAG_A, FLAG_B, FLAG_C>::WithValues<0x01, 0x02, 0x04> MyFlags. Typically, they will be used with the values that are powers of two (although not always, in some cases certain combinations would be made, for example one could imagine a set of flags like Read=0x1, Write=0x2, and ReadWrite=0x3=0x1|0x2). I would like to provide a way to do typedef Flags<unsigned char, FLAG_A, FLAG_B, FLAG_C>::WithDefaultValues MyFlags.
template<class _B, template <class,class,_B> class... _Fs>
class Flags
{
public:
template<_B... _Vs>
class WithValues :
public _Fs<_B, Flags<_B,_Fs...>::WithValues<_Vs...>, _Vs>...
{
// ...
};
};
I have tried the following without success (placed inside the Flags class, outside the WithValues class):
private:
struct _F {
// dummy class which can be given to a flag-name template
template <_B _V> inline constexpr
explicit _F(std::integral_constant<_B, _V>) { } };
// we count the flags, but only in a dummy way
static constexpr unsigned _count = sizeof...(_Fs<_B, _F, 1>);
static inline constexpr
_B pow2(unsigned exp, _B base = 2, _B result = 1) {
return exp < 1 ?
result :
pow2(exp/2,
base*base,
(exp % 2) ? result*base : result);
}
template <_B... _Is> struct indices {
using next = indices<_Is..., sizeof...(_Is)>;
using WithPow2Values = WithValues<pow2(_Is)...>;
};
template <unsigned N> struct build_indices {
using type = typename build_indices<N-1>::type::next;
};
template <> struct build_indices<0> {
using type = indices<>;
};
//// Another attempt
//template < _B... _Is> struct indices {
// using WithPow2Values = WithValues<pow2(_Is)...>;
//};
//template <unsigned N, _B... _Is> struct build_indices
// : build_indices<N-1, N-1, _Is...> { };
//template < _B... _Is> struct build_indices<0, _Is...>
// : indices<_Is...> { };
public:
using WithDefaultValues =
typename build_indices<_count>::type::WithPow2Values;
Of course, I would be willing to have any other alternatives to the whole situation (supporting both flag names and values in the same template set, etc).
I have included a "working" example at ideone: http://ideone.com/NYtUrg - by "working" I mean compiles fine without using default values but fails with default values (there is a #define to switch between them).
Thanks!

So I figured it out on my own, I guess I posted too soon.
I was able to get around the error generated with the given code with a dummy template argument in the build_indices and indices template classes above. The argument has to be a typename as they currently have variadic integral types.
(Note: still using the improper _F names here - I have corrected my personal code to not use these reserved name - thanks for the tip)
Here is a working solution which results in the WithValues<...> template to be filled with powers of 2 (1, 2, 4, 8, 16, ...) based on the size of the Flags variadic template.
private:
// dummy class which can be given to a flag-name template
struct _F
{
template <_B _V> inline constexpr
explicit _F(std::integral_constant<_B, _V>) { }
};
// we count the flags, but only in a dummy way
static constexpr unsigned _count = sizeof...(_Fs<_B, _F, 1>);
static inline constexpr
_B pow2(unsigned exp, _B base = 2, _B result = 1)
{
return exp < 1 ?
result :
pow2(exp/2, base*base, (exp % 2) ? result*base : result);
}
template <class dummy, _B... _Is> struct indices
{
using next = indices<dummy, _Is..., sizeof...(_Is)>;
using WithPow2Values = WithValues<pow2(_Is)...>;
};
template <class dummy, unsigned N> struct build_indices
{
using type = typename build_indices<dummy, N-1>::type::next;
};
template <class dummy> struct build_indices<dummy, 0>
{
using type = indices<dummy>;
};
public:
using WithDefaultValues =
typename build_indices<void, _count>::type::WithPow2Values;

Related

How to initialize tuple of vectors out of a variadic template pack and list of objects which use the same template types?

Below is a simplified description of what I intend to do and the code with which I'm approaching it.
I have a structure TEmitter<Ts...> where Ts... is a list of components stored in a std::tuple inside of TEmitter.
Lets say there are two emitters:
e1<A, B, C>
e2<A, B, C>
I'd like to create a class EmitterMemory<Ts...> which takes an std::initializer_list<TEmitter<Ts...>> in the constructor, takes the components of each TEmitter apart, and puts them in std::vectors which are stored in a tuple, like:
EmitterMemory<A, B, C> {e1, e2}
(has a) stl::tuple
|-stl::vector<A> = [A(e1), A(e2)]
|-stl::vector<B> = [B(e1), B(e2)]
|-stl::vector<C> = [C(e1), C(e2)]
Now in the code below I think I've managed to declare the class EmitterMemory correctly, I just don't know how to initialize the std::tuple<std::vector<Ts>...> out of the constructor parameter std::initializer_list<TEmitter<Ts...>>.
I'd need somehow to iterate through the components declared in variadic template Ts..., and for each of them invoke get<T>(TEmitter<Ts...>) and put the result inside the std::vector<T>.
Something that I'm manually doing in the 4 last lines of the main() function.
I'd need some help how to approach this, so it's done automatically in the class constructor.
Can you tell me if it's feasible?
Code
#include <concepts>
#include <functional>
#include <iostream>
struct ComponentBase{};
template<typename T>
concept is_a_component = std::is_base_of_v<ComponentBase, T>;
template<typename ...T>
concept is_many_components = (is_a_component<T> && ...);
namespace components {
struct Position : ComponentBase {};
struct Shoot : ComponentBase {};
struct Active : ComponentBase {};
struct Emission : ComponentBase {};
}
struct EmitterBase {};
template<typename T>
concept is_an_emitter = std::is_base_of_v<EmitterBase, T>;
template<is_many_components... Ts>
class TEmitter : EmitterBase {
using Components = std::tuple<Ts...>;
public:
explicit TEmitter(int id) : id{id} {};
int id{0};
Components components = std::make_tuple(Ts()...);
};
template<is_a_component T>
auto &get(is_an_emitter auto &emitter) {
return std::get<T>(emitter.components);
}
struct EmitterMemoryBase {};
template<is_many_components... Ts>
class EmitterMemory : EmitterMemoryBase {
using TupleOfVectors = std::tuple<std::vector<Ts>...>;
public:
static constexpr std::size_t AmountComponents = sizeof...(Ts);
TupleOfVectors components;
EmitterMemory(std::initializer_list<TEmitter<Ts...>> emitters)
: components { std::make_tuple<>(std::vector<Ts>{}...) }
{ };
};
template<typename ...Ts>
concept is_a_memory = std::is_base_of_v<EmitterMemoryBase, Ts...> ;
template<is_a_component T>
auto &get(is_a_memory auto &memory) {
return std::get<std::vector<T>>(memory.components);
}
int main () {
using namespace components;
auto e1 = TEmitter<Position, Shoot, Active>{1};
auto e2 = TEmitter<Position, Shoot, Active>{2};
auto &e1_position_component = get<Position>(e1);
auto &e2_position_component = get<Position>(e2);
auto memory = EmitterMemory<Position, Shoot, Active>({e1, e2});
auto &position_vector = get<Position>(memory);
position_vector.emplace_back(e1_position_component);
position_vector.emplace_back(e2_position_component);
}
Not exactly as you asked... with a variadic list of elements instead of an initializer list... but adding an helper method, should works as follows
template <typename T, typename ... Ems>
static std::vector<T> getVect(Ems const & ... ems)
{ return { get<T>(ems)... }; }
template <typename ... Ems>
EmitterMemory (Ems const & ... ems)
: components { getVect<Ts>(ems...)... }
{ }
Obviously you have to initialize memory
auto memory = EmitterMemory<Position, Shoot, Active>(e1, e2);
without brackets.
If you really want to use a std::initializer_list (but why?) you can send it to getVect() and unpack it inside the body of the method with a classic range-for.
Unrequested Bonus
Using the variadic constructor, you can add an explicit deduction guide
template <typename ... Es, typename ... Ts>
EmitterMemory (TEmitter<Es...>, Ts...) -> EmitterMemory<Es...>;
so you can initialize memory simply as follows
auto memory = EmitterMemory(e1, e2);
because the is_main_components... Ts template parameters (Position, Shoot, Active, in this case) are deduced from the first argument (e1).
Obviously this works if you initialize memory with at least an argument.

How do I get access to template parameters of a template pack parameter

I am trying to create a template class that will enable a compare function to return an integer [ 0 - equal, >0 a should come first, <0 b should come first ].
I am using Sort structs template parameters to keep track of the type that should be used, offset of the field in the string, as well as the order that this field should be kept... so compare can according return the correct value.
Assume for now that the std::string is used to represent a serialized value.
I am having trouble with extracting the information from the template. I have kept sort as a pack parameter, which would be of the type Sort. How do I access these parameters in the code? If there is a better way to refactor this. I looked at some of the other questions related to templates, but didn't see any that would solve this problem. I am using gcc 8.2 and c++17.
#include <cstdint>
#include <string>
#include <cstring>
#include <cassert>
template<typename T, uint32_t offset, char Order = 'A'>
struct Sort {};
template<uint32_t keyLength, template<typename T,uint32_t offset, char Order> class ... sort>
class Comparator {
public:
int compare(std::string & a, std::string &b) {
assert(a.length()==b.length());
// How would I sum the sizeof each T. i.e. if T is int and another T is short, then sum should be 6+keyLength?
assert(a.length()==(sizeof(T)+keyLength)); // Check that my length is equal to key length + all type lengths put together
auto r = memcmp(a.data(),b.data(),keyLength);
if(r!=0) return r;
// How do I retrieve T,offset,Order of each pack parameter.
return internal_compare<T,offset,Order>(a.data(),b.data())? internal_compare<T,offset,Order>(a.data(),b.data()) : ...;
}
private:
template<typename IT,uint32_t iOffset, char iOrder>
int internal_compare(char * a,char *b) {
if constexpr (iOrder=='A'||iOrder=='a') {
return (*(static_cast<IT *>(a+iOffset)))-(*(static_cast<IT *>(b+iOffset)));
} else {
return (*(static_cast<IT *>(b+iOffset)))-(*(static_cast<IT *>(a+iOffset)));
}
}
};
Two things I have not been able to accomplish.
One is getting the sum of sizeof(T) from the sort.
Call the internal compare operator on each sort.
Link to code on compiler explorer
This becomes substantially easier if instead of using this form:
template<typename T, uint32_t offset, char Order = 'A'>
struct Sort {};
template<uint32_t keyLength, template<typename T,uint32_t offset, char Order> class ... sort>
class Comparator;
You use this one:
template <uint32_t keyLength, class...>
class Comparator;
template <uint32_t keyLength, typename... T, uint32_t... offset, char... Order>
class Comparator<keyLength, Sort<T, offset, Order>...> {
// ...
};
First, the original didn't do what you wanted to do anyway. You wanted specific instantiations of Sort but you were actually accepting class templates... like Comparator<32, Sort, Sort, Sort>. Which presumably isn't meaningful.
But when we do it this way, we're not only accepting only instantiations of Sort but we have the parameters in the most useful form. So something like this:
// How would I sum the sizeof each T. i.e. if T is int and another T is short,
// then sum should be 6+keyLength?
Is a fold-expression:
(sizeof(T) + ... + keyLength)
And so forth.
I'll take this problem on another front: how do you extract the template parameters if T has template parameters? Here's an example:
template<typename T>
void foo(T v) {
// T is std::vector<int>, how to extract `int`?
}
int main() {
foo(std::vector{1, 2, 3, 4});
}
There's many answers to that: extraction using partial specialization, type aliases and others.
Here's how you can do it for std::vector:
template<typename>
struct extract_value_type_t {};
template<typename T>
struct extract_value_type_t<std::vector<T>> {
using type = T;
};
template<typename T>
using extract_value_type_t = typename extract_value_type<T>::type;
template<typename T>
void foo(T v) {
// with template specialization
using value_type = extract_value_type_t<T>;
// with the member alias std::vector exposes
// needs much less boilerplate!
using value_type = typename T::value_type;
}
What does doing it with T when it's a vector gives us? Well, if you can do something with a simple type T, you won't even need a template template parameter, making your interface more flexible:
template<typename>
struct sort_traits {};
template<typename T, uint32_t offset_, char order_>
struct sort_traits<Sort<T, offset_, order_>> {
using type = T
static constexpr auto offset = offset_;
static constexpr auto order = order_;
};
Then in your Comparator class, simply do something like that:
template<uint32_t keyLength, typename... sorts>
struct Comparator {
int compare(std::string const& a, std::string const& b) {
return (internal_compare<sorts>(a.data(), b.data()) && ...);
}
private:
template<typename sort>
int internal_compare(char const* a, char const* b) {
using traits = sort_traits<sort>;
using type = typename traits::type;
constexpr auto offset = traits::offset;
constexpr auto order = traits::order;
// do stuff
}
};
This also add the possibility one day to add another kind of sort that would have different template parameters or different things exposed.

c++ Default paramaters: is it possible to override a default parameter without overriding earlier default parameters

I have a function:
int function(int a, int b = 1, int c = 2){
return a+b+c;
}
I want to set the value of the "c" variable to 3, but don't want to set the value of "b"
In a language like python I can do this:
function(23,c=3)
However in c++ I cant find a way to do something like that. All examples I could find involved setting the value of "b" before the value of "c", like this:
function(23,1,3);
How can I set the value of a default parameter directly?
This is not possible in C++ (at least not directly). You have the provide all parameters up to the last one you want to provide, and in the order given by the declaration.
You can not do that in C++.
As a workaround you could wrap all parameters as fields with default value in a class (or a struct). You can then have multiple constructors for that class that allow you to set only those fields you are really interested in changing with respect to default.
It is possible in c++... if you're willing to jump through some hoops.
For fun, here is an example of how it might be done:
#include <iostream>
#include <tuple>
#include <type_traits>
#include <utility>
//
// utility to check whether a type is in a list of types
//
template<class T, class...Ts> struct is_in;
template<class T, class U>
struct is_in<T, U>
: std::is_same<T, U>::type {};
template<class T, class U, class...Rest>
struct is_in<T, U, Rest...>
: std::integral_constant<bool, std::is_same<T, U>::value || is_in<T, Rest...>::value>
{};
//
// a wrapper around fundamental types so we can 'name' types
//
template<class Type, class Tag>
struct fundamental {
using value_type = Type;
using tag_type = Tag;
fundamental(Type x) : _x(x) {}
operator const Type&() const { return _x; }
operator Type&() { return _x; }
Type _x;
};
//
// a utility to figure out a fundamental type's value or to take it's default value if it's not present
//
template<class Fundamental, class Tuple, typename = void>
struct value_of_impl
{
static typename Fundamental::value_type apply(const Tuple& t)
{
return Fundamental::tag_type::dflt;
}
};
template<class Fundamental, class...Types>
struct value_of_impl<Fundamental, std::tuple<Types...>, std::enable_if_t<is_in<Fundamental, Types...>::value>>
{
static typename Fundamental::value_type apply(const std::tuple<Types...>& t)
{
return typename Fundamental::value_type(std::get<Fundamental>(t));
}
};
template<class Fundamental, class Tuple>
decltype(auto) value_of(const Tuple& t)
{
return value_of_impl<Fundamental, Tuple>::apply(t);
}
//
// some tag names to differentiate parameter 'name' types
//
struct a_tag { static constexpr int dflt = 0; };
struct b_tag { static constexpr int dflt = 1; };
struct c_tag { static constexpr int dflt = 2; };
//
// define some parameter 'names'
//
using a = fundamental<int, a_tag>;
using b = fundamental<int, b_tag>;
using c = fundamental<int, c_tag>;
//
// the canonical implementation of the function
//
void func(int a, int b, int c)
{
std::cout << a << ", " << b << ", " << c << std::endl;
}
//
// a version that forwards the values of fundamental types in a tuple, or their default values if not present
//
template<class...Fundamentals>
void func(std::tuple<Fundamentals...> t)
{
func(value_of<a>(t),
value_of<b>(t),
value_of<c>(t));
}
//
// a version that converts a variadic argument list of fundamentals into a tuple (that we can search)
//
template<class...Fundamentals>
void func(Fundamentals&&...fs)
{
return func(std::make_tuple(fs...));
}
//
// a test
//
using namespace std;
auto main() -> int
{
func();
func(a(5));
func(c(10), a(5));
func(b(20), c(10), a(5));
return 0;
}
expected output:
0, 1, 2
5, 1, 2
5, 1, 10
5, 20, 10
You can't do that directly, but you can use Named Parameter Idiom (although criticized).
The idea is to create an object encapsulating all parameters, initialize it using method chaining and finally call the function, so the code would look like:
int v = function(params(23).c(3));
Something like this could be done with the named parameter idiom. Here's how it might look in use to have optional parameters (sans the default parameter values):
/*
int function(int a, int b = 1, int c = 2){
return a+b+c;
}
*/
int function( Parameters &p ) {
/* ... */
}
void someOtherFunction() {
function( Parameters().parmW(/*...*/)
/* parmX was omitted here */
.parmY(/*...*/)
.parmZ(/*...*/)
);
Adding default parameters could be done in a few ways. function could be replaced with a class whose purpose is to perform those actions. Parameters could also be written to know which flags were set, then function passes in default values before it begins executing. I'm sure there's plenty of ways to do this, perhaps some a lot better than what I've suggested.

Changing enum values based on HW selection

What is the best way to design a function where the allowed enum value changes based on the HW selected for example. The function might look like this, this won't compile but hopefully you get the idea.
enum class EHWUnit
{
Unit0,
Unit1,
Unit2
};
enum class EHWType
{
Type1,
Type2,
Type3,
Type4
};
SelectHWinput( const EHWUnit aUnit, const EHWType aHWType, const unit8_t aSelect )
{
if( aHWType & 1 == 0)
ArrayIS( 2,4,6,8,10)
else
ArrayIS( 1,3,5,7,9)
element = ArrayIS(aSelect)
WriteToRegister( Address, bits, element);
}
Does anyone know of a way to make it better to select the element based on type? I would prefer to somehow link those even elements to the type at compile time and not select them at run time, using one function is there anyway to make this code more fool proof?
A shot in the dark, as I'm not sure what exactly it is you want to do.
It seems like you want to make some compile-time decisions, which could look something like this:
enum EHWUnit
{
Unit0,
Unit1,
Unit2
};
enum EHWType
{
Type1,
Type2,
Type3,
Type4
};
template <int Select>
struct ArrayIS
{
static constexpr int const array[] = {1, 3, 5, 7, 9};
};
template <int Select>
constexpr int const ArrayIS<Select>::array[];
template <>
struct ArrayIS<0>
{
static constexpr int const array[] = {2, 4, 6, 8, 10};
};
constexpr int const ArrayIS<0>::array[];
template <EHWUnit aUnit, EHWType aHWType, int aSelect>
struct SelectHWinput
{
static constexpr int get()
{
return ArrayIS<static_cast<int>(aHWType) & 1>::array[aSelect];
}
};
int main()
{
// To illustrate that the value is selected at compile-time, a
// static assertion that will always fail:
static_assert(SelectHWinput<Unit0, Type1, 0>::get() < 0, "Works, value selected at compile-time");
}
In the code above, Template Metaprogramming (TMP) is used to select a value of one of the arrays at compile-time. The correct array is chosen by supplying the Select template non-type parameter. Because these arrays are declared constexpr, a constexpr member-function can be used to extract one of its element at compile-time. The static_assert proves that it works.
If you want to construct the arrays more flexibly at compile-time, I suggest looking at this question of mine, where I describe TMP-functors to construct static arrays at compile-time:
g++ (4.7.2) bug or feature, when initializing static arrays at compile-time?
EDIT:
You said you were interested in the Array implementation:
template <typename T, size_t Count, template <typename, T> class Function, T Current, T ... Elements>
struct Array_: public Array_<T, Count - 1, Function, Function<T, Current>::result, Elements ..., Current>
{};
template <typename T, template <typename, T> class Function, T Current, T ... Elements>
struct Array_<T, 0, Function, Current, Elements...>
{
constexpr static std::array<T, sizeof...(Elements)> array = {{Elements ...}};
};
template <typename T, size_t Count, T Start = T(), template <typename, T> class Function = Null>
struct Array: public Array_<T, Count, Function, Start>
{};
Here, the last one is the one you'll use, using a Template Metaprogramming functor that tells the compiler how to generate the next element from the previous one. This is a limitation, but it's the best I could come up with at the time.
Three simple functors that you could use:
template <typename T, T Value>
struct Null
{
enum { result = Value };
};
template <typename T, T Value>
struct Increment
{
enum { result = Value + 1 };
};
template <typename T, T Value>
struct Decrement
{
enum { result = Value - 1 };
};
For example, if you need an array with incremental values from 1 to 100, you would do this:
std::array<int, 100> arr = Array<int, 100, 1, Increment>::array;
This array is then allocated and populated at compile-time.

C++ metaprogramming

I have the following problem:
Suppose I have some basic counter class Counter. And suppose we also have some sets of classes, that can be counted. Let's name some of them class CountedA and class CountedB.
Now, every class, which can be counted (such as CountedA and CountedB) has the following statically declared parts: one enum and one int part, that acts like a part of counted data.
For example, it's declaration could look the following way:
enum CountedType { A, B };
template <CountedType Type, int N>
class Counted { };
// Now we can declare 'CountedA' and 'CountedB'
typedef Counted<A, 25> CountedA;
typedef Counted<B, 7> CountedB;
Now, the declaration of the counter:
// C++0x variadic or simply bunch of 'typename XX' definitions for C++03
template <typename T0, typename T1, typename ...>
class Counter
{
// I don't know how to implement this
// for now!
int GetTotalN() { ... }
// Retrieve the corresponding type
// so that GetTypeAt<0> returns
// enum from 'T0'
template <int Pos>
CountedType GetTypeAt() { ... }
};
I want to be able to write something like:
class RealCounter : public Counter<CountedA, CountedB> { };
And use it the following way:
RealCounter counter;
int n = counter.GetTotalN();
CountedType type = counter.GetTypeAt<0>();
Now, I'm pretty sure that this can be done. But what's the best way of implementing it? (don't ask me why would I need such crazy kind of things :)
Does boost::mpl offer something for this case?
Thank you.
Small update:
In this particular example, GetTotalN() should return 25 + 7.
If we add, for example, typedef Counted<C, 2> CountedC, then the result for
RealCounter : public Counter<CountedA, CountedB, CountedC>
should become 25 + 7 + 2.
Here's C++03 code which works (for up to 10 template arguments). The main trick is giving class Counter a multiple inheritance, and passing objects of type Counter to function templates which must select a base class. The actual summation is done recursively.
Counter.hpp
enum CountedType { A, B };
template <CountedType Type, int N>
struct Counted {};
struct DummyCounted {};
template <int Pos, typename T>
struct IndexedType {};
template <unsigned int Terms>
struct PartialSum
{
template <typename CounterT>
static int getSum(const CounterT& ctr)
{ return PartialSum<Terms-1>::getSum(ctr) + ctr.template GetNAt<Terms>(); }
};
template <> struct PartialSum<0U>
{
template <typename CounterT>
static int getSum(const CounterT& ctr)
{ return ctr.template GetNAt<0>(); }
};
template <typename T0, typename T1=DummyCounted,
typename T2=DummyCounted, typename T3=DummyCounted,
typename T4=DummyCounted, typename T5=DummyCounted,
typename T6=DummyCounted, typename T7=DummyCounted,
typename T8=DummyCounted, typename T9=DummyCounted>
class Counter :
public IndexedType<0, T0>, public IndexedType<1, T1>,
public IndexedType<2, T2>, public IndexedType<3, T3>,
public IndexedType<4, T4>, public IndexedType<5, T5>,
public IndexedType<6, T6>, public IndexedType<7, T7>,
public IndexedType<8, T8>, public IndexedType<9, T9>
{
public:
static int GetTotalN() {
return PartialSum<9>().getSum( Counter() );
}
template <int Pos>
static CountedType GetTypeAt() { return _getTypeAt<Pos>( Counter() ); }
template <int Pos>
static int GetNAt() { return _getNAt<Pos>( Counter() ); }
private:
template <int Pos, CountedType Type, int N>
static CountedType _getTypeAt(const IndexedType<Pos, Counted<Type,N> >&)
{ return Type; }
template <int Pos, CountedType Type, int N>
static int _getNAt(const IndexedType<Pos, Counted<Type,N> >&)
{ return N; }
template <int Pos>
static int _getNAt(const IndexedType<Pos, DummyCounted>&)
{ return 0; }
};
Counter.cpp
#include "Counter.hpp"
#include <iostream>
typedef Counted<A, 25> CountedA;
typedef Counted<B, 7> CountedB;
class RealCounter : public Counter<CountedA, CountedB> {};
int main()
{
RealCounter counter;
int n = counter.GetTotalN();
CountedType type = counter.GetTypeAt<0>();
std::cout << "n is " << n
<< "\ntype check is " << (type == A) << std::endl;
return 0;
}
Output:
n is 32
type check is 1
That C++0x variadic template stuff looks interesting, but I haven't taken a good look at it yet. But I do think in C++0x, all this example's functions (except main of course) could be constexpr.
I'm not sure why you need to embed those parameters in the templates arguments and not simply in a constructor since they are all the same types for each "derived" CountedA/B types.
Anyways you can embed the resulting types into a std::tuple as shown in the link below (see Message class for an example). Then create a variadic template function similar to the applyTuple version in the link below that will add all your integer arguments and return the final result once all arguments have been unrolled. As for the returning of the enum value for the item in "Pos" simply call the get( tuple ).getEnum() or .value to get it.
How do I expand a tuple into variadic template function's arguments?