How to "splice" function arguments?
I have the following situation with parallel overloaded functions: void f(X *x) | void f(int g, X *x) { { | { Impl<false>::f(-1, x); | Impl<true>::f(g, x); } | } template<bool F> struct Impl { typedef Detail<F> detail; void f(int g, X *x) { // CODE X *t = detail::smth(g, x); // CODE } }; In the "false" case, the argument g of Impl::f is not used and I want to get rid of it in compile-time as an optimization. The rest of the CODE is completely identical. In other words, I want to transform the "false" case, at compile-time, to the following: void f(X *x) { Impl<false>::f(x); } template<> struct Impl<false> { typedef Detail<false> detail; void f(X *x) { // CODE X *t = detail::smth(x); // CODE } }; Now, I could manually duplicate all of the code in Impl::f(int, X*) into Impl::f(X*) and remove the extra argument in the call to detail::smth. Doing such specialization manually seems _very_ inelegant and error-prone (I'm not really a fan of copy-pasting the code :)) Is there a better way; ie. doing it automatically? If so, how? It is acceptable to manually overload the top-level f() function, as it has no other code except the dispatch to Impl::f. I want full compile-time solution; ie. I do not want the stack space for the unneeded integer parameter ever to be allocated. [The code for the "false" case will be called on every function invocation, so YES, performance DOES matter even without apriori profiling.] Signatures in the implementation of Impl and Detail are flexible and I can change them if it helps solving the problem. The only thing that I do not want to change are the signatures of top-level f() function overloads. Thanks, Zeljko.
----- Mensaje original -----
De: Zeljko Vrba
I have the following situation with parallel overloaded functions:
void f(X *x) | void f(int g, X *x) { { | { Impl<false>::f(-1, x); | Impl<true>::f(g, x); } | }
template<bool F> struct Impl { typedef Detail<F> detail;
void f(int g, X *x) { // CODE X *t = detail::smth(g, x); // CODE } };
In the "false" case, the argument g of Impl::f is not used and I want to get rid of it in compile-time as an optimization. The rest of the CODE is completely identical.
In other words, I want to transform the "false" case, at compile- time, to the following:
void f(X *x) { Impl<false>::f(x); }
template<> struct Impl<false> { typedef Detail<false> detail;
void f(X *x) { // CODE X *t = detail::smth(x); // CODE } };
[...] Something like the following? struct X; template<bool> struct detail; template<> struct detail<true> { static X* smth(int,X*); }; template<> struct detail<false> { static X * smth(X*); }; template<bool> struct impl_arg; template<> struct impl_arg<true> { impl_arg(int g,X* x):g(g),x(x){} int g; X* x; }; template<> struct impl_arg<false> { impl_arg(X* x):x(x){} X* x; }; X* call_smth(impl_arg<true> arg) { return detail<true>::smth(arg.g,arg.x); } X* call_smth(impl_arg<false> arg) { return detail<false>::smth(arg.x); } template<bool F> struct impl { static void f(impl_arg<F> arg) { // code with arg.x call_smth(arg); // code with arg.x } }; void f(X* x) { impl<false>::f(impl_arg<false>(x)); } void f(int g,X* x) { impl<true>::f(impl_arg<true>(g,x)); } Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
participants (2)
-
"JOAQUIN LOPEZ MU?Z"
-
Zeljko Vrba