Is it possible to write two template functions as one when the only difference is the argument constant?
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 Foob
accept const T&
, while others Foob
only accept T&
s, or the same one Foob
may even have two proc
s, one for the case const
, one for the non- const
case, which does different things.
However, the code is do_it
the same: it's simple f.proc(t)
. Sometimes the code is many lines, but still identical. Is there a way to write do_it
as one function? Something like this, although it clearly wouldn't work:
template <class Foob, class MaybeConst, class T>
void do_it(Foob& f, MaybeConst T& t) { f.proc(t); }
source to share
Actually, if the argument is t
always lvalue, then you only need the first overload! If the lvalue is of type const U
, then the template parameter t
is inferred as const U
, and the type of the second instance of the second function will be const U&
, which will be bound to the lvalue constant just fine.
The second overload is only needed if the argument is an rvalue. But instead of making it 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)); }
source to share