c++ creating templated objects programmatically - c++

Suppose I want to instantiate many objects that come from a templated class (something like std::bitset) from bitset<1> to bitset<10>.
for (size_t i = 1; i <= 10; ++i) {
std::bitset<i> my_bitset;
// do stuff with it...
}
obviously this won't compile because i is not a literal or a constexpr.
Is there a way to do this? I'm thinking everything template metaprogramming possible in my head but I can't figure this one out. Any pointers appreciated.

It is not possible, as you realized, to use a runtime variable as a template parameter; however should you know the list of values to use at compile-time, then you can indeed have a way to invoke tests for each element of this list.
template <template <size_t> class F>
void run() {}
template <template <size_t> class F, size_t H, size_t... Tail>
void run() { F<H>()(); run<F, Tail...>(); }
Then it is just a matter of defining F:
template <size_t N>
struct BitSetPlay {
void operator()() {
std::bitset<N> b;
b.flip();
std::cout << b.to_ulong() << "\n";
}
};
Putting it altogether:
#include <bitset>
#include <iostream>
template <template <size_t> class F>
void run() {}
template <template <size_t> class F, size_t H, size_t... Tail>
void run() { F<H>()(); run<F, Tail...>(); }
template <size_t N>
struct BitSetPlay {
void operator()() {
std::bitset<N> b;
b.flip();
std::cout << b.to_ulong() << "\n";
}
};
int main() {
run<BitSetPlay, 1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u, 10u>();
return 0;
}
Note: this assumed a possibly discontiguous list, if it is a range you wish for then you can do without variadic templates by simply keeping track of the bounds.

It's not possible, because templates are a compile-time only concept. You can't use runtime data to declare templated instances.
Template arguments have to be types, or compile-time constants.

Something like (not tested):
template<int N>
struct InstantBS
{
std::bitset<N> bs;
InstantBS<N-1> next;
};
template<>
struct InstantBS<0>
{
};
template struct InstantBS<10>; //instantiate bitset<1> to bitset<10>
UPDATE: Well, I have tested it, and it does not work! The problem is that the members of InstantBS are not implicitly instantiated. And unfortunately, explicit instantiation must occur at namespace level, so you cannot force a explicit instantiation from another explicit instantiation. Unfortunately, template namespaces are not invented yet...
The closest think I can devise is this, doing manual instantation of any member of the bitset you need:
template<int N>
struct InstantBS
{
void DoThings()
{
std::bitset<N> bs;
bs.set();
bs.reset();
bs.flip();
//any other operation you want to instantiate
InstantBS<N-1> next;
next.DoThings();
}
};
template<>
struct InstantBS<0>
{
void DoThings()
{
}
};
template struct InstantBS<10>; //instantiate bitset<1> to bitset<10>, more or less
You can check that the requestet members of the bitsets are actually instantiated:
$ g++ -c test.cpp
$ objdump -t test.o | c++filt | grep bitset

see docs:
The size of a bitset is fixed at compile-time (determined by its template parameter). For a class that also optimizes for space allocation and allows for dynamic resizing, see the bool specialization of vector (vector).

Related

How do I implement inheritance in a partial class template specialisation?

I think I'm just missing something small. I want to specialize the constructor of a templated class for an implementation where T = the template class with any parameter. Sorry if my vocab is a bit off.
Basically, I need to allow for jagged 2D arrays, so I might have a ArEl<ArEl<int>> and I would like to preinitialise all the array lengths.
using namespace std;
template <typename T>
class ArEl {
public:
ArEl(size_t size = 0)
: rSize(size), rArray(rSize ? new T[rSize]() : nullptr) {}
ArEl(const ArEl& other);
virtual ~ArEl() { delete[] rArray; }
void swap(ArEl& first, ArEl& second);
void redim(size_t size);
private:
std::size_t rSize;
T* rArray;
};
template <typename T, typename T1>
class ArEl<ArEl<T>> : public ArEl<T1>{
ArEl(size_t size = 0);
};
EDIT:
I'm getting this error:
error: template parameters not deducible in partial specialization:
class ArEl<ArEl<T>> : public ArEl<T1>{
You're specializing your object in the wrong way.
template<typename T, typename T1> implies that there's two datatypes that need to be provided, but it's clear that the only thing your template specialization needs is the datatype of the underlying array(s). If the expectation is that ArEl<ArEl<T>> be specialized, it shouldn't take more than this:
template<typename T>
class ArEl<ArEl<T>> {
/*Blah Blah Blah*/
};
There's no need for inheritance, and no need for a second datatype.
However, I'll also add: there's not really any need for this specialization in the first place. If you don't write the specialization at all, the following code should still work as-is:
ArEl<ArEl<int>> dim2Array(50);
//I'm assuming ArEl will have a member size() function
for(size_t index = 0; index < dim2Array.size(); index++) {
//I'm assuming ArEl will have an operator[] overload
dim2Array[index].redim(30);
}
//dim2Array is now 50 int arrays, each of size 30.
I'm assuming that the functionality you're intending is to have something like the following, which does require template specialization like what I posted above:
ArEl<ArEl<int>> dim2Array(50, 30);
//dim2Array is now 50 int arrays, each of size 30.
But if I were you, I'd leave the implementation of ArEl alone and instead invest in writing a Matrix<T> class (or possibly Matrix<T, N>, for N-dimensions) that handles this kind of syntax instead (which you could build using ArEl<T> as the building blocks, incidentally), especially because I don't think you're committed to writing the specializations for ArEl<ArEl<ArEl<int>>> or deeper (and yes, the way you're trying to do it, each level would need its own specialization).
Specializing an entire class implies replacing all the members with the ones provided by the specialization. You don't want that.
One option would be to provide all the members that need specialization in a base class: BaseForA<T> would be specialized, and A<T> would derive from it.
Another one would be to use tag dispatching, here's an example of how you can use it to do different actions depending on the type parameter.
#include <iostream>
#include <type_traits>
template<typename T>
struct tag {};
template<typename T>
struct A
{
private:
template<typename U>
A(std::size_t s, tag<A<U>>)
{
std::cout << "special constructor " << s << "\n";
}
A(std::size_t s, ...)
{
std::cout << "general constructor " << s << "\n";
}
public:
A(std::size_t s = 0) :
A(s, tag<T>())
{
}
};
int main()
{
A<int> a;
A<A<int>> b;
A<A<long>> c;
A<long> d;
}
Live on Coliru
If I understand you correctly you want the specialised version to inherit the generic version and then add something on top of it. The problem here is that you have a specialised ArEl<ArEl<T>>, you cannot request a generic version of it.
The solution is to make the generic version and the specialised version be different types.
template<typename T, bool D=true>
class ArEl { ...
template<typename T>
class ArEl<ArEl<T>>:
public ArEl<ArEl<T>, false> { ...
But now the problem is that ArEl<T, true> and ArEl<T, false> are unrelated and incompatible!
The solution is to introduce a common base class for them.
template<typename T>
class ArElBase {
... all functionality of ArEl
};
template<typename T, bool D=true>
class ArEl : public ArElBase<T> {
using ArElBase<T>::ArElBase;
// nothing more
};
and then the specialisation, unchanged.
Now you can use ArElBase to pass your objects by pointer or reference, but use ArEl to declare objects themselves.

How is nested template specialization done C++

I have a templated function defined as:
template<typename TObject> TObject Deserialize(long version, const Value &value)
what I need to do, is to write a specialization which would take vector defined as:
template<typename TNum, int cnt> class Vec
and still has access to cnt and TNum.
I have unsuccesfully tried
template<typename TNum, int cnt> Vec<TNum, cnt> Deserialize<Vec<TNum, cnt>>(long version, Value &value)
resulting in error: illegal use of explicit template arguments
What is the correct way to do it?
Usually, the correct answer to dealing with function templates and needing to partially specialize them, is to simply overload them instead. In this case this trick doesn't work directly because there are no arguments that depend on the template parameter, i.e. the template parameter is explicitly specified and not deduced. However, you can forward along to implementation functions, and make overloading work by using a simple tag struct.
#include <functional>
#include <iostream>
#include <type_traits>
#include <vector>
#include <array>
template <class T>
struct tag{};
template<typename TObject>
TObject Deserialize_impl(long version, tag<TObject>) {
std::cerr << "generic\n";
return {};
}
template<typename T, std::size_t N>
std::array<T,N> Deserialize_impl(long version, tag<std::array<T,N>>) {
std::cerr << "special\n";
return {};
}
template<typename TObject>
TObject Deserialize(long version) {
return Deserialize_impl(version, tag<TObject>{});
}
int main() {
Deserialize<int>(0);
Deserialize<std::array<int,3>>(0);
return 0;
}
Live example: http://coliru.stacked-crooked.com/a/9c4fa84d2686997a
I generally find these approaches strongly preferable to partial specialization of a struct with a static method (the other major approach here) as there are many things you can take advantage with functions, and it behaves more intuitively compared to specialization. YMMV.
While the functional tag-dispatch is a nice approach, here's a class specialization version for comparison. Both have their use, and I don't think either is an inherently regrettable decision but maybe one matches your personal style more.
For any class you write that needs a custom deserialize handler, just write a specialization of the Deserializer class:
#include <iostream>
#include <string>
using namespace std;
using Value = std::string;
// default deserialize function
template <typename TObject>
struct Deserializer {
static TObject deserialize(long version, const Value &value) {
std::cout << "default impl\n";
return TObject();
}
};
// free standing function (if you want it) to forward into the classes
template <typename TObject>
TObject deserialize(long version, const Value &value) {
return Deserializer<TObject>::deserialize(version, value);
}
// Stub example for your Vec class
template<typename TNum, int cnt> class Vec { };
// Stub example for your Vec deserializer specialization
template <typename TNum, int cnt> struct Deserializer<Vec<TNum, cnt>> {
static auto deserialize(long version, const Value &value) {
std::cout << "specialization impl: cnt=" << cnt << "\n";
return Vec<TNum, cnt>();
}
};
int main() {
Value value{"abcdefg"};
long version = 1;
deserialize<int>(version, value);
deserialize<Vec<int, 10>>(version, value);
}
Ideally in this situation, Vec should reflect its own template parameters as members Vec::value_type and Vec::size() which should be constexpr.
If the class fails to provide its own properties in its own interface, the next best thing is to define your own extension interface. In this situation, you can have separate metafunctions (like accessor functions), or a traits class (like a helper view class). I'd prefer the latter:
template< typename >
struct vector_traits;
template< typename TNum, int cnt >
struct vector_traits< Vec< TNum, cnt > > {
typedef TNum value_type;
constexpr static int size = cnt;
};
template<typename TVec> TVec Deserialize(long version, Value &value) {
typedef vector_traits< TVec > traits;
typedef typename traits::value_type TNum;
constexpr static int cnt = traits::size;
…
}
This solution fits into any existing function, and even makes the signatures cleaner. Also, the function is more flexible because you can adapt it by adding traits specializations instead of entire new overloads.

What is the most compact way to extract the template arguments of a class and iterate over them?

In the little program below, I show the solution I currently use to extract the template arguments of a class and iterate over it via a recursive helper function.
I wonder if there is a more concise way to do it, as I explain in the pseudo-code in the comments below.
template <int...Is> struct Pack {};
template <int I> struct B
{
static void foo() { std::cout << I << "\n"; }
};
// recursive helper function, also used to extract the parameter pack arguments
template <int I, int...Is>
void foo_helper( Pack<I, Is...>&& )
{
B<I>::foo();
foo_helper( Pack<Is...>{} );
}
// terminate recursion
void foo_helper( Pack<>&& ) {}
struct A
{
typedef Pack<1,3,5> ints;
static void foo()
{
// this is what I do
foo_helper(ints{});
// this is what I would like to do, ideally in one single line
// 1) extract the template arguments pack from ints, without creating an helper function for that
// 2) iterate on the template arguments of the pack without a recursive helper
// In pseudocode, something like:
// (B<IterateOver<ArgumentsOf<ints>>>::foo());
}
};
int main()
{
A::foo();
}
If you want to do metaprogramming, start working in types. If you want non-type template parameters, move them over to types asap.
Below, I first take Pack<1,2,3> and convert it to types< std::integral_constant<int, 1>, std::integral_constant<int, 2>, std::integral_constant<int, 3> >. This is a list of types that is in obvious correspondence to your pack of ints.
Then, I introduce a tag type template. This is a type which "carries" another type, but it itself is stateless. You can extract the type from an value of an instance of the template as a bonus.
Third, I write a "for each type" function that takes a lambda and a pack of types, and proceeds to call the lambda once for each of the types, passing in a tag type.
In the body of the lambda, we can extract the passed type by using decltype on the tag variable (or a helper macro).
We chain those together, and from the passed tag type we can extract the integer in the original pack.
The result is you can inject this into your code:
for_each_type( [&](auto tag){
constexpr int i = TAG_TYPE(tag){};
// use i
}, ints_as_types_t<ints>{} );
in the middle of your method, and work on the ints "inline".
If we wanted to only solve your specific problem, we'd do a bit less boilerplate, but I like the genericness.
template<class...>struct types{using type=types;};
template <int...Is> struct Pack {};
template<class pack> struct ints_as_types;
template<class pack>
using ints_as_types_t=typename ints_as_types<pack>::type;
template<class T, template<T...>class pack, T...ts>
struct ints_as_types<pack<ts...>> {
using type=types<std::integral_constant<T,ts>...>;
};
now we can do:
using pack = ints_as_types_t<Pack<1,2,3>>;
and pack is a list of types, not a list of integers.
Now some hana-style metaprogramming: (metaprogramming with values instead of pure types)
template<class T>struct tag_t{using type=T; constexpr tag_t(){};};
template<class T>constexpr tag_t<T> tag={};
template<class Tag>using type_t=typename Tag::type;
#define TAG_TYPE(...) type_t<std::decay_t<decltype(__VA_ARGS__)>>;
template<class F, class...Ts>
void for_each_type(F&& f, types<Ts...>) {
using discard=int[];
(void)discard{ 0, ((
f(tag<Ts>)
),void(),0)...};
}
which lets you iterate over a collection of types.
for_each_type( [&](auto tag){
constexpr int i = TAG_TYPE(tag){};
// use i
}, ints_as_types_t<ints>{} );
gives you a lambda that has a constexpr int i for each of the types in your list.
A bunch of the above work lifts your list of ints into a list of types, because working with only types makes metaprogramming less special-case. You can skip that lifting, and write a for_each_integer that takes a Pack<int...> directly with less code, but it seems less useful to me.
You could add a foo_for_each function to Pack:
template <int...Is> struct Pack {
template <template <int> class T>
static void foo_for_each () {
std::initializer_list<int> { (T<Is>::foo(),0)... } ;
}
};
Then you would just write:
ints::foo_for_each<B>();
This will call B<N>::foo for each N in the pack.
As suggested by Yakk, you could pass in a lambda which gets a tag type as an argument to create a generic Pack::for_each:
template <typename T> struct tag { using type = T; };
template <typename T> using type_t = typename T::type;
template <int...Is> struct Pack {
template <template <int> class T, typename Func>
static void for_each (Func&& func) {
std::initializer_list<int> {
((std::forward<Func>(func)(tag<T<Is>>{})) 0)...
} ;
}
};
Then you could call like this:
auto call_foo = [](auto tag) { type_t<decltype(tag)>::foo(); };
ints::for_each<B>(call_foo);
This is the shortest I can come up with:
#include <iostream>
template<int... Is>
struct Pack;
template <int I> struct B
{
static void foo() { std::cout << I << "\n"; }
};
template<typename PACK> struct unpack;
template<int...Is>
struct unpack<Pack<Is...>>
{
template<template<int> class T>
static void call()
{
using swallow = int[sizeof...(Is)];
(void) swallow{(T<Is>::foo(), 0)...};
}
};
struct A
{
typedef Pack<1,3,5> ints;
static void foo()
{
unpack<ints>::call<B>();
}
};
int main()
{
A::foo();
}
If you want to have the variadic pack for runtime-iteration you could attach a std::arrayto your struct Pack as:
template <int...Is> struct Pack {
std::array<int, sizeof...(Is)> arr = {{Is...}};
};
And then iterate through as:
static void foo() {
for(auto && i : ints{}.arr) std::cout << i << " ";
}
Live Demo
What you wrote here is just plain weird, where did you even find an implementation this
rigid ?
You NEED a helper function, it's just a fact, you could probably work around it
somehow, but I do not see the point of that.
The only solution for that, right now, is to use Clang 3.6, they already implemented
the new syntax, that allows you to write something like this.
// I am pretty sure, this was the syntax, it's called a fold expression
// you can read more about it here:
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4295.html
template<typename ... Type>
auto sum(Type ... argument)
{
return (... + argument);
}
In any other compiler, the way to go about it, is to write two simple functions
template<typename Tail>
auto sum(Tail tail)
{
return tail;
}
template<typename Head, typename ... Tail>
auto sum(Head head, Tail ... tail)
{
return head + sum(tail);
}
This accepts anything that supports + so strings, ints, doubles will work, probably
some more, but you get the gist of it.
Your example would look like this
template<typename Tail>
void print(Tail tail)
{
cout << tail << endl;
}
template<typename Head, typename ... Tail>
void print(Head head, Tail ... tail)
{
cout << head;
print(tail...);
}
Usage:
print(1, 3.14, "something", string{"yeye"}, 52);
or
sum(1, 512, 55, 91);
There are some other ways to use variadic templates, like this guy here describes,
there is way too much of it, for me to put it here, so I'll just link:
http://florianjw.de/en/variadic_templates.html
Iterating over the arguments of a template is a bit harder, because you have to use
some real compiler magic and index_sequence.
I have an example lying around here somewhere, because I have been messing around
with it lately.
template<typename InputTuple, std::size_t ... N>
void tupleIteratorImpl(InputTuple& input, std::index_sequence<N...>)
{
// DO WHATEVER YOU WANT HERE, but the structure is
FUNCTION(/* pass all of the template parameters as arguments */, std::get<N>(input)...);
// and FUNCTION has to have the structure of the examples from point 1.
// but with this, you can already do pretty much anything you imagine
// even at compile time
}
template<typename InputTuple, typename Indices = std::make_index_sequence<std::tuple_size<InputTuple>::value>>
void tupleIterator(InputTuple& input)
{
tupleIteratorImpl(input, Indices());
}
A function for this is already included in c++17, and it is called apply, here's the documentation:
http://en.cppreference.com/w/cpp/experimental/apply with some sample code even.
Hope this answers some of your questions.

Recursive variadic function template

I want to write a class method that takes a template parameter pack, but zero arguments, and "iterate" over the types:
struct Bar {
template <typename T, typename... Ts>
void foo() {
// something with T that involves Bar's members
foo<Ts...>();
}
};
What is the preferred way to implement this?
You may use the following:
struct Bar {
template <typename... Ts>
void foo() {
int dummy[] = {0 /*Manage case where Ts is empty*/,
(bar<Ts>(), void() /* To avoid overload `operator,` */, 0)...};
(void) dummy; // suppress warning for unused variable.
}
template <typename T>
void bar()
{
// something with T that involves Bar's members
}
};
In C++17, it can be simplified with Folding expression:
struct Bar {
template <typename... Ts>
void foo() {
(static_cast<void>(bar<Ts>()), ...);
}
template <typename T>
void bar()
{
// something with T that involves Bar's members
}
};
template<class...Fs>
void do_in_order(Fs&&...fs) {
int _[]={0, ( std::forward<Fs>(fs)(), void(), 0 )...};
(void)_;
}
hides the syntax required to execute a pack of function objects in left to right order.
Then:
struct Bar {
template <class... Ts>
void foo() {
do_in_order([&]{
using T = Ts;
// code
}...);
}
};
and in a conforming compiler, we will run the // code with T being each type from left to right.
Note that some compilers claiming to be C++11 compilers may fail to compile the above.
The advantage of this technique is that it hides the nasty "expand and evaluate templates" code within a function with a clear name. You write do_in_order once, and it usually suffices for almost every use of that array-expansion trick.
There are a two important reasons to use this kind of esoteric syntax instead of the "more simple" recursive solutions.
First, it makes things easier for the optimizer. Optimizers sometimes give up after a pile of recursive calls.
Second, the sum of the lengths names of the function signatures for the traditional recursive functions grow at O(n^2). If you use helper types, the total length of the names is also O(n^2). Unless you are careful, this can cause compile time, link time, and binary size bloat.
In C++1z there are plans for some "fold" syntax that may make the esoteric parts of the above less esoteric.
I like overloaded functions and using a typelist:
#include <iostream>
#include <typeinfo>
template <typename ...Ts> struct typelist { };
void foo_impl(typelist<> )
{
// we are finished
}
template <typename T, typename ...Ts>
void foo_impl(typelist<T, Ts...> )
{
std::cout << typeid(T).name() << ", ";
foo_impl(typelist<Ts...>{});
}
template <typename ...Ts>
void foo()
{
std::cout << "called with <";
foo_impl(typelist<Ts...>{});
std::cout << ">" << std::endl;
}
int main()
{
foo<int, char, float>();
}

Template classes with specialised constructors

Consider the following contrived example of a templated array definition:
template <typename t, unsigned int n> class TBase
{
protected:
t m_Data[n];
//...
};
template <typename t, unsigned int n> class TDerived : public TBase<t, n>
{
TDerived()
{
}
};
I can specialize this type to provide a non-default constructor for an array of length 2 as follows:
template <typename t> class TDerived<t, 2> : public TBase<t, 2>
{
public:
TDerived(const t& x0, const t& x1)
{
m_Data[0] = x0;
m_Data[1] = x1;
}
};
int main()
{
TDerived<float, 2> Array2D_A(2.0f, 3.0f); //uses specialised constructor
TDerived<float, 3> Array3D_A; //uses default constructor
return 0;
}
Is there some other way I can create a class that has different constructor options constrained against template parameters at compile-time without the requirement for a complete class specialisation for each variation?
In other words, is there some way I can have specialised constructors in the TBase class without the need for the intermediary step of creating TDerived whilst preserving the functionality of TBase?
I think deriving your class from a base class is not relevant to the question here, that's a mere implementation detail. What you really seem to be after is if there's a way to partially specialize member functions, like the constructor. Do you want something like this?
template <typename T, int N> class Foo
{
Foo(); // general
template <typename U> Foo<U, 2>(); // specialized, NOT REAL CODE
};
This doesn't work. You always have to specialize the entire class. The reason is simple: You have to know the full type of the class first before you even know which member functions exist. Consider the following simple situation:
template <typename T> class Bar
{
void somefunction(const T&);
};
template <> class Bar<int>
{
double baz(char, int);
};
Now Bar<T>::somefunction() depends on T, but the function only exists when T is not int, because Bar<int> is an entirely different class.
Or consider even another specialization template <> class Bar<double> : public Zip {}; -- even the polymorphic nature of a class can be entirely different in a specialization!
So the only way you can provide specializations new declarations of members, including constructors, is by specializing the entire class. (You can specialize the definition of existing functions, see #Alf's answer.)
There are basically two options I see for this:
Use a variadic function for construction (ie. "..." notation), you can use the value n inside that function to get your arguments from the stack. However, the compiler will not check at compile time if the user provides the correct number of arguments.
Use some serious template magic to allow a call chaning initialization, that would look like this: vector(2.0f)(3.0f). You can actually build something that at least ensures the user does not provide too many arguments here. However tha mechanism is a little more involved, I can assemble an example if you want.
You can always specialize a member, e.g.
#include <stdio.h>
template< class Type >
struct Foo
{
void bar() const
{ printf( "Single's bar.\n" ); }
};
template<>
void Foo< double >::bar() const
{ printf( "double's bar.\n" ); }
int main()
{
Foo<int>().bar();
Foo<double>().bar();
}
But you want effectively different signatures, so it's not directly a case of specializing a member.
One way forward is then to declare a constructor with a single argument, of a type dependent on the template parameters.
Then you can specialize that, as you want.
Cheers & hth.,
Since constructor is a function, you need to fully specialize the containing class to address your specific problem. No way out.
However, functions cannot be partially specialized (in all compilers). So suppose if you know that you need n = 2 when t = int or double then following is one alternative.
template<>
TDerived<int,2>::TDerived()
{
//...
}
template<>
TDerived<double,2>::TDerived()
{
//...
}
and so on.
[Note: If you use MSVC, then I think it supports partial specialization; in that case you can try:
template<typename t>
TDerived<t,2>::TDerived()
{
//...
}
though, I am not sure enough for that.]
You could give the most common definitions in the non-specialized class and static_assert (BOOST_STATIC_ASSERT for non C++0x) on the array length. This could be considered a hack but is a simple solution to your problem and safe.
template<typename T, unsigned int n>
struct Foo {
Foo(const T& x) { static_assert(n == 1, "Mooh!"); }
Foo(const T& x1, const T& x2) { static_assert(n == 2, "Mooh!"); }
};
The "evil" way would be variadic arguments.
template<typename T, unsigned int n>
struct Foo {
Foo(...) {
va_list ap;
va_start(ap, n);
for(int j=0; j < n; ++j)
bork[j] = va_arg(ap, T);
va_end(ap);
}
};
Then there is also C++0x and the good old make_something trick which is more difficult then one would think.
template<typename... T, unsigned int n>
Foo<T, n> make_foo(T&&...) {
// figure out the common_type of the argument list
// to our Foo object with setters or as a friend straight to the internals
Foo< std::common_type< T... >::type, sizeof(T) > foo;
// recursive magic to pick the list apart and assign
// ...
return foo;
}