Topic: Templates with variable number of parameters?


Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1997/09/05
Raw View
Has there been any thought on templates with variable number of
parameters? (Of course you can use a template function declaraion
with ..., but that's not what I think of).
If yes, why was this not adopted (or was it, and I'm just not aware
of it)?

A thought on how it could be done (I know it's too late to
incorporate something like this to the standard):

template<typename result, typelist args>
 result call_with_lock(result (*f)(args), args a)
{
  lock();
  result res=f(a);
    // all the args are passed to f with correct types (overloading!)
  unlock();
  return res;
}

void f();
int g(int, char*);
double h(vector<double>&, int);

void foo()
{
  vector<double> v;
  call_with_lock(f);
     // void call_with_lock<void, ()>(void (*)())
  int k=call_with_lock(g, 3, "test");
     // int call_with_lock<int, (int, char*)>(int (*)(), int, char*)
  double d=call_with_lock(h, v, 2);
     // double call_with_clock<double, (vector<double>&, int)>
     //     (double (*)(vector<double>&, int), vector<double>&, int)
}

To access individual arguments of an argument list, one could
define the following:

a[0]      gives the number of arguments
a[2]      gives the second argument
a[-3]     gives the third-from-last argument
a[2,4]    gives a sublist from the secont to the fourth argument

In addition, there could be a "pseudo loop" statement
(normal loops won't work because of different types -> different
function calls):

for n:a
  cout << a[n];

would for example translate to

cout << a[1];
cout << a[2];
cout << a[3];
...
cout << a[-2];
cout << a[-1];

To loop from the second one, the following construct could be used:

for n:a[2,-1] // loop over the sublist from second arg to last arg
  f(a[1], a[n]);

Any comments on this?
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Kristian Kvilekval <krisk@osti.com>
Date: 1997/09/08
Raw View
Christopher Eltschka wrote:
>
> Has there been any thought on templates with variable number of
> parameters? (Of course you can use a template function declaraion
> with ..., but that's not what I think of).
> If yes, why was this not adopted (or was it, and I'm just not aware
> of it)?
>
> A thought on how it could be done (I know it's too late to
> incorporate something like this to the standard):
>
> template<typename result, typelist args>
>  result call_with_lock(result (*f)(args), args a)
> {
>   lock();
>   result res=f(a);
>     // all the args are passed to f with correct types (overloading!)
>   unlock();
>   return res;
> }

You can get pretty close to what you want to do using functor
objects from STL and defining several template based on the number
of arguments. For example (for one arg)..

template <class unary_functor> class call_with_lock_unary
{
public:
 unary_functor::return_type operator () (unary_functor::argument_type
arg){
  lock();
  unary_functor::return_type x = unary_functor (arg);
  unlock();
  return x;
 }
};


A few years ago I brought the variable arglist up under under the
heading of writing a handle class template. Here is a synopsis

I wanted to write a generic handle template for C++ classes with method
forwarding, such
that for any class
class B
{
public:
 void op1();
 int op2(int) const;
}

I could write
handle<B>  hb ( new B)
handle<B>  new_b (hb);  // new_b points to same rep as hb.
 new_b->op2(1);  // new_b still points to same rep as hb.
 new_b->op1();  // new_b now has a new representation (op1) is not a
// constant method.

in order to do this I needed a way of forwarding argument lists
template<class T> class handle
{
public:
 template<method op>
  op::return_type operator -> (op::typelist args)
  {
   // copy representation of T
   clone();
   return op (args);
  }
 template<const method op>
  op::return_type operator -> (op::typelist args)
  {
   return op (args);
  }

private:
 T* ptr;
};



maybe this argument could resurrected?
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]