I have some code that was written before we had c++11 compilers across our platforms. Finally we can start using c++11 features as the last platform has finally caught up. As a result, I am trying to cleanup some of the long "function with N arguments via copy-pasting" chains with variardic templates. However, I will admit that I don't quite know how to solve the following case. I have a Format() method that packs arguments into variants and then passes them into a function buried in a source file (to reduce bloat, include dependencies, etc). How do I unpack the template arguments into an array to pass into the method?
struct Variant
{
enum ValueType { Integer, Float };
Variant(int _value) { value._asInt = _value; valueType = Integer}
// ... and other constructors
union Value
{
int _asInt;
// ... other types including specific user types
} value;
ValueType valueType;
};
// Implementation burried in source file
extern size_t FormatStringImpl(const char* format, char * dest, size_t capacity, Variant variants[], size_t numVariants);
template<class T0>
size_t Format(const char* format, char* dest, size_t capacity, T0 var0)
{
Variant variants[] = { Variant(var0) };
return FormatStringImpl(format, dest, capacity, variants, sizeof(variants) / sizeof(variants[0]));
}
template<class T0, class T1>
size_t Format(const char* format, char* dest, size_t capacity, T0 var0, T1 var1)
{
Variant variants[] = { Variant(var0), Variant(var1) };
return FormatStringImpl(format, dest, capacity, variants, sizeof(variants) / sizeof(variants[0]));
}
// and on and on
void foo()
{
const size_t length = 1024;
char output[length];
Format("Values are {0}, {1}, {2}", output, length, 10, 20, 30);
}
The details are somewhat more complex, but the gist of it is a way to capture the type/data and pull it into the source file for processing. I would like to perform all allocations on the stack so using a std::vector in an unpack loop here won't work.
Format
can be simplified to:
template<class ... Ts>
size_t Format(const char* format, char* dest, size_t capacity, Ts... vars)
{
Variant variants[] = { Variant(vars)... };
return FormatStringImpl(format, dest, capacity, variants, sizeof...(vars));
}
I also replaced sizeof(variants) / sizeof(variants[0])
by sizeof...(vars)