C++0x will allow template to take an arbitrary number of arguments. What is the best use of this feature other than implementing tuples ?
8 Answers
- Type-safe printf
- Forwarding of arbitrary many constructor arguments in factory methods
- Having arbitrary base-classes allows for putting and removing useful policies.
- Initializing by moving heterogenous typed objects directly into a container by having a variadic template'd constructor.
- Having a literal operator that can calculate a value for a user defined literal (like "10110b").
Sample to 3:
template<typename... T> struct flexible : T... { flexible(): T()... { } };
Sample to 4:
struct my_container { template<typename... T> my_container(T&&... t) { } };
my_container c = { a, b, c };
Sample to 5:
template<char... digits>
int operator "" b() { return convert<digits...>::value; }
See this example code: here

- 1
- 1

- 496,577
- 130
- 894
- 1,212
Maybe the talk by Andrei Alexandrescu on the Going Native 2012 event, will be of your interest:

- 12,806
- 9
- 48
- 94
- Type-safe
printf

- 530,221
- 131
- 937
- 1,214
-
Yes, but I still have to see a very elegant implementation of that :-) – Nicola Bonelli Nov 09 '08 at 18:02
-
I think this specific example is somewhat of a degenerate case. Remember that for every instantiation the compiler needs to create more code. can you imagine creating 100+ versions of printf for every possible argument combination used? Oh the bloat! – shoosh Nov 09 '08 at 19:33
-
2@Shy: not if all the versions are inline wrappers for the *real* printf. – CesarB Nov 09 '08 at 20:22
-
@shoosh: The "main" function can be a loop unrolled into (inline) sequential operations, each working on one (templated) function parameter. – Fred Nurk Feb 08 '11 at 21:09
Allowing things like Boost.Function to take arbitrary numbers of parameters

- 131,367
- 29
- 160
- 239
I have implemented an NDArray (N-dimentional array) and it has the method setSizes with variadic count of arguments. Using variadic template arguments is type safer than using variadic function arguments, moreover I can control count of parameters passed to this function in compile time only with variadic template arguments.
void setSizes(uintmax_t currentSize) {
static_assert(1 == NDimensions, "Invalid count of arguments given to setSizes.");
size_ = currentSize;
data_ = new NDArrayReferenceType[currentSize];
}
template <typename... Sizes>
void setSizes(uintmax_t currentSize, Sizes... sizes) {
static_assert(sizeof...(Sizes) + 1 == NDimensions, "Invalid count of arguments given to setSizes.");
size_ = currentSize;
data_ = new NDArrayReferenceType[currentSize];
for (uintmax_t i = 0; i < currentSize; i++) {
data_[i]->setSizes(sizes...);
}
}
I have also implemented a universal constructor wrapper for my self-made SmartPointer. It wraps over all user-defined constructor of type of raw pointer.
template <typename TSmartPointer, typename... Args>
static inline void initialize(TSmartPointer *smartPointer, Args... args) {
smartPointer->pointer_ = new typename TSmartPointer::PointerType(std::forward<Args>(args)...);
smartPointer->__retain();
}
This code seems to be inobvious, this is a part of initializer of the SmartPointer for the case whether SmartPointer should automatically call the constructor of pointer at the acquisition of the SmartPointer (RAII). In case of abstract classes it is unable to call the constructor.
So, if I have a type AbstractObject, which is SmartPointer of an abstract class, and the type ConcreteObject, which is SmartPointer of class with constructor that takes two ints, I can write following code:
AbstractObject object = ConcreteObject(42, 42);
It is like C# and Java (but with RAII) and it works for me in C++/GCC 4.8 =)

- 639
- 5
- 8
Type-safe printf has been mentioned in other answers, but more generally variadic templates can be used to implement formatting functions that don't require passing type information via format specifiers at all. For example, the C++ Format library implements formatting functions similar to Python's str.format:
fmt::print("I'd rather be {1} than {0}.", "right", "happy");
in addition to safe printf. The types of arguments are captured automatically using variadic templates in C++11.
This makes printf specifiers like lld
or notorious PRIdPTR
unnecessary and instead of
std::printf("Local number: %" PRIdPTR "\n\n", someIntPtr);
one can simply use
fmt::printf("Local number: %d\n\n", someIntPtr);
Disclaimer: I'm the author of this library

- 49,672
- 25
- 199
- 336