c++ - passing multiple rvalues and lvalues to a function without creating overloads -
assume providing client library function has multiple reference arguments.
for sake of simplicity lets assume have 3 arguments , various references int (so can assume, these constants created initializer_list).
from call site should possible pass ad hoc created constants (rvalue) functions (think of testing code in case) real references objects being owned entity.
so far i've come following solutions:
void bar(int &x, int &y, int &z) { } // use template wrapper turn rvalues lvalues. template <typename t, typename u, typename v> void foo(t &&t, u &&u, v &&v) { bar(t,u,v); } // create humongous amount of overloads void baz(int &&x, int &y, int &z) { } void baz(int &x, int &&y, int &z) { } void baz(int &&x, int &&y, int &z) { } void baz(int &x, int &y, int &&z) { } void baz(int &&x, int &y, int &&z) { } void baz(int &x, int &&y, int &&z) { } void baz(int &&x, int &&y, int &&z) { } // claim ownership of objects , create temporaries void bam(int x, int y, int z) { } int main() { int = 1; foo(i,2,3); foo(2,i,3); foo(2,3,i); bar(i,2,3); // doesn't compile bar(2,i,3); bar(2,3,i); baz(i,2,3); // requires 8 overloads baz(2,i,3); baz(2,3,i); return 0; } i'm not satisfied of solutions every 1 of them has drawbacks. there cleaner alternative problem?
this question not trivial there guidelines have evolved on years , have not changed c++11. following assume have side-effect free, free-standing function (guidelines different constructors , member functions).
what recommend free-standing function is:
- pass primitive data types (int, double, bool, etc.) value
- pass complex data types const reference (e.g. const std::vector&) unless need copy within function pass value
- if function templated use const reference (e.g. const t&) since both lvalue , rvalue bind const references
- if function templated , intend perfect forward use forwarding references (e.g. t&&, called universal references)
so example using integers use bam function:
void bam(int x, int y, int z) { } there interesting talk herb sutter given @ cppcon last year among other stuff covers input arguments functions: https://www.youtube.com/watch?v=xnqtkd8ud64
another interesting post on stackoverflow related question: correct usage of rvalue references parameters
update constructors:
the main difference constructors recommendations above stronger emphasis on copying input , making object owned class. same holds setters. main reason safer resource management (to avoid data races or accessing invalid memory).
Comments
Post a Comment