Search code examples
c++templatesvariadic-templatesrvalue-referencelvalue

C++ Function taking lvalue and rvalue parameters transparently


I'm looking for a way to make function declarations that can take either lvalues or rvalues as parameters without much hassle.

This question, Function that accepts both lvalue and rvalue arguments, provides a workaround that works but needs to be implemented "manually". For instance, a function:

void test(T& or T&&);

could be implemented as:

void test(T&) { code... }; void test(T&& t) { test(t); };

The problem with this is that as the number of parameters grow, the number of declarations that you have to type "manually" also increases, sadly, in an exponential manner (2^n_parameters).

So, for a function like:

void complex(A& or A&&, B& or B&&, C& or C&&, D& or D&&, E& or E&&);

You would have to type 32 different signatures and that's the problem.

The idea is that one should be able to call this function with any combination of lvalue/rvalue parameters, like:

string s("SOMETHING");
complex(string("SOMETHING"), s, "SOMETHING", ...); // SHOULD WORK

But declaring complex only once and having some kind of automated process that generates everything else that's needed.

Could this be solved with variadic templates and some kind of currying emulation?

Macros maybe? Or what do you think?


Solution

  • If you don't need to modify the objects, you can simply accept by const reference:

    void test(T const &);
    

    This will bind to both lvalues and rvalues.