Claudiu
Claudiu

Reputation: 229371

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); }

Upvotes: 4

Views: 131

Answers (1)

Brian Bi
Brian Bi

Reputation: 119219

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)); }

Upvotes: 11

Related Questions