Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to write two template functions as one when the only difference is the const-ness of an argument?

I have something like:

template <class Foob, class T>
void do_it(Foob& f, T& t) { f.proc(t); }

template <class Foob, class T>
void do_it(Foob& f, const T& t) { f.proc(t); }

Some Foobs take const T&s while other Foobs take just T&s, or the same Foob may even have two procs, one for the const case, one for the non-const case, that do different things.

However, the code of do_it is the same: it's just f.proc(t). Sometimes the code is many lines, but still identical. Is there any way to write do_it as just one function? Something like this, though this would clearly not work:

template <class Foob, class MaybeConst, class T>
void do_it(Foob& f, MaybeConst T& t) { f.proc(t); }
like image 235
Claudiu Avatar asked Sep 11 '25 10:09

Claudiu


1 Answers

Actually if the t argument is always an lvalue then you only need the first overload! If the lvalue has type const U, then the template parameter T is deduced as const U and the instantiated function's second parameter type will be const U&, which will bind to the const lvalue just fine.

The second overload is only needed if the argument is an rvalue. But instead of making that a special case, why not just use perfect forwarding?

// works for both lvalues and rvalues with any cv-qualification
template <class Foob, class T>
void do_it(Foob& f, T&& t) { f.proc(std::forward<T>(t)); }
like image 129
Brian Bi Avatar answered Sep 13 '25 01:09

Brian Bi