views:

207

answers:

4
+3  Q: 

Variadic templates

Hi all,

I have seen a lot of links introduced the variadic templates. But I have never seen one compilable example that demonstrates this approach?

Could someone provides me some links in which such compilable examples can be found?

regards Sami

+2  A: 
phadej
yes, I looked at it. I tried to create an example to to compile it without success. I need an compilable example which, as I said, demonstrates this approach by running it
sami
+3  A: 

Variadic templates are part of the C++0x standard which is not yet officially released. They are supported by gcc since version 4.3, but you need to enable support for C++0x by adding the compiler switch -std=c++0x.

David Feurle
Right. And as far as I know, the Microsoft Compiler doesn't yet support variadic templates. Just saying.
sellibitze
+5  A: 

Variadic templates are a C++0x feature that primarily targets authors of generic libraries. I would not expect to see them in "user code". For example, in the C++0x standard library they are used in a lot of places: std::function, std::async, std::reference_wrapper, std::tuple, std::packaged_task, ...

To give you an example I'll show you how a reference_wrapper might be implemented with respect to variadic templates:

template<class T>
class reference_wrapper
{
    T *ptr;
public:
    explicit reference_wrapper(T& thing) : ptr(&thing) {}
    explicit reference_wrapper(T&&     ) = delete;

    operator T&() const {return *ptr;}

    template<class... Args>
    decltype( declval<T&>()(declval<Args>()...) )
    operator()(Args&&... args) const
    {
        return (*ptr)(forward<Args>(args)...);
    }
};

This is not perfectly conforming to the standard draft but it is supposed to be compilable with little modification. It demonstrates multiple C++0x features:

  • deleted functions (disabling the constructor for rvalues)
  • rvalue references (detecting rvalue arguments to the constructor, perfect forwarding)
  • type deduction via decltype
  • standard library function template declval to create objects for the purpose of building an expression for decltype (GCC does not yet offer this function template. You have to write it yourself)
  • variadic templates (accepting an arbitrary number of parameters)

The purpose of the variadic member template is to forward arguments to the object referred to by ptr. This should work in case T is a function pointer type or a class type with overloaded function call operator.

cheers! s

sellibitze
+2  A: 

One of the simplest possible examples is the following implementation of max which isn't even templated on types.

int maximum(int n)
{
    return n;
}

template<typename... Args>
int maximum(int n, Args... args)
{
    return max(n, maximum(args...));
}

Only slightly more complex is the canonical printf implementation:

void printf(const char *s)
{
  while (*s)
  {
    if (*s == '%' && *(++s) != '%')
      throw "invalid format string: missing arguments";
    std::cout << *s++;
  }
}

template<typename T, typename... Args>
void printf(const char* s, T value, Args... args)
{
  while (*s)
  {
    if (*s == '%' && *(++s) != '%')
    {
      std::cout << value;
      printf(s, args...); // call even when *s == 0 to detect extra arguments
      return;
    }
    std::cout << *s++;
  }
  throw "extra arguments provided to printf";
}
Motti