
Hello, although this is not strictly a Boost-related question I wonder whether some of the utilities in Boost (enable_if, type_traits) can help me solve the problem: Say I've got the following template function template<typename T> void call_f(int x) { T t; t.f(x); } whose purpose is to invoke t.f(x) on an object of type T: struct foo { void f(int){} }; struct bar { static void f(int){}; }; ... call_f<foo>(5); call_f<bar>(5); And now I'd like to optimize call_f's implementation by avoiding the creation of the T object when it is not necessary (as in bar, whose memfun f is static). The following will do for simple cases like foo and bar above: template<typename T,typename R,typename A> void call_f_impl(int x,R(*)(A)) { T::f(x); } template<typename T,typename Q> void call_f_impl(int x,Q) { T t; t.f(x); } template<typename T> void call_f(int x) { call_f_impl<T>(x,&T::f); } but fails when f is a memfun template: struct baz { template<typename T> void f(T){} }; ... call_f<baz>(5); For instance, Comeau says: "ComeauTest.c", line 17: error: no instance of overloaded function "call_f_impl" matches the argument list The argument types that you used are: (int, <unknown-type>) call_f_impl<T>(x,&T::f); ^ detected during instantiation of "void call_f<T>(int) [with T=baz]" at line 42 1 error detected in the compilation of "ComeauTest.c". Any idea about how to solve this in a more comprehensive way? Thank you in advance, Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

<joaquin <at> tid.es> writes:
And now I'd like to optimize call_f's implementation by avoiding the creation of the T object when it is not necessary (as in bar, whose memfun f is static).
IMHO this is unnecessary if you are only interested in avoiding the small object instatiation. I expect the compiler to erase them. I once played with template code that had nesting levels of 50 and more with function calls calling functions calling ... etc. ... calling C-library code. Using link time optimization destroyed all of those: the first step in debugger went right through to the C-library call. The compiler sorted it out for me. No smybols of my own code in a symbol table print. OTOH this remains an interesting question: Might be useful if you want to ensure to grab only those classes with the static version for reasons other than runtime performance. Markus

________________________________________ De: boost-users-bounces@lists.boost.org [boost-users-bounces@lists.boost.org] En nombre de Markus Werle [numerical.simulation@web.de] Enviado el: lunes, 25 de agosto de 2008 16:03 Para: boost-users@lists.boost.org Asunto: Re: [Boost-users] Detecting memfun staticness
<joaquin <at> tid.es> writes:
And now I'd like to optimize call_f's implementation by avoiding the creation of the T object when it is not necessary (as in bar, whose memfun f is static).
IMHO this is unnecessary if you are only interested in avoiding the small object instatiation. I expect the compiler to erase them.
That's what I also expected... until proven wrong by real life :( This has come up as part of my work for the post-review version of Boost.Flyweight: going from t.f(x) to T::f(x) in one critical part of the library resulted in a release mode 3x speedup when accessing the values associated to flyweight objects. This was with MSVC++ 8.0, which I consider rather good at optimizing chores. With GCC 3.4 for Cygwin the differences are even higher. The "t" in "t.f(x)" looks clearly droppable (it does not take part in the evluation of f(x)), but the compiler refuses to do the optimization. FWIW, that "t" is not constructed on every call but merely a reference to it is recovered via a singleton API. This singleton is implemented as a Meyers singleton, i.e. as a static local object, which as you know makes the compiler generate initialization code to construct the local object the first time the context is entered; I wonder whether this side effect is what's preventing the compiler from omitting the reference recovering altogether.
OTOH this remains an interesting question: Might be useful if you want to ensure to grab only those classes with the static version for reasons other than runtime performance.
If you have a clue I'd love to hear about it :) Joaquín M López Muñoz Telefónica, Investigación y Desarrollo
participants (3)
-
JOAQUIN M. LOPEZ MUÑOZ
-
joaquin@tid.es
-
Markus Werle