Re: Perfect Forwarding in Runtime (rvalue reference)
Am Donnerstag, 28. Juni 2012 11:17:12 UTC+2 schrieb dervih:
[...]
But what about a non-template function? Using overloads I have to write
8 different function declartations for 3-parameters function
(for n-params function => 2^n)
Why authors of rvalue reference concepts have not decided to extend
perfect forwarding for non-template functions.
Of cource it is not obvious how it could be implemented neigher
if it is generally possible.
But after couple of hours I realized that it is possible and
the implemntation is quite inexpensive and nice.
Below it is my proposition. In order for a function to take parameters
both as a lvalue or rvalue reference
the new type specyficator &^ should be definde. The function
signature will look like:
fun( A&^, B&^, C^& )
One signature and one implemntation. Now consider the body and
parameter usage.
fun( A&^ a, B^& b, C^& c ) {
[plain a, b, c are lvalues]
gun( ^a, ^b, c ); // a b as original reference or copy,
// c as lvalue reference or copy
}
In the last line the new prefix operator ^ (restore reference operator)
occured that dinamically restores original reference kind.
[...]
Of course the decision can not be done during compilation time. So
compilator should generate a swich respecting all possibilities.
What about the possibilities that don't work? For example, in case there is=
no overload of gun which accepts an rvalue as first parameter? Should this=
generate an exception?
Also, I can imagine that generating calls to all possible overloads might t=
rigger a lot of template instantiations (consider gun to be a function temp=
late) which could trigger compilation errors because not every combination =
is supported/needed.
The last thing is that gun singatures have match to all possible
variant calls from fun in order for no unmatch errors to occur in runtime=
..
And this can be simply check in compilation time.
This sort of checking is not possible at compile time (because a function d=
eclaration is not enough to see whether a call would "work" or not). But it=
is theoretically possible at link-time. The generation of the "invocation =
switch" could be deferred to link-time and only made to include the calls t=
hat are actually needed in the whole program (this would also eliminate the=
template instantiation issue I mentioned earlier). But this approach doesn=
't seem to work with dynamic linking libraries unless you include runtime-c=
ompilation in the whole process. Requiring C++ implementations to do link-t=
ime code generation alone seems already too much to ask for, IMHO.
If you're worried about unnecessary code duplication you might implement 'f=
un' from your example like this:
void fun_impl(A& a, B& b, C& c) {
f(a);
a = A();
}
template<class T, class U>
void fun(T&& a, U&& b, C c) {
fun_impl(a,b,c);
gun(forward<T>(a),forward<U>(b),move(c));
}
or hope on the toolset to automatically detect and compensate for redundanc=
ies across different instantiations of function templates. I actually don't=
know how well compilers and linkers are able to do this kind of "code bloa=
t reduction" on their own.
Cheers!
SG