Prev: Detecting when a function in a CRTP base class is hidden
Next: Why does inserter need Iterator template parameter
From: Cory Nelson on 15 Feb 2010 13:09 Hello all, I am using CRTP (the Curiously Recurring Template Pattern) like so: template<T> struct base { void do_something() { prepare(); static_cast<T*>(this)->hide_me(); finalize(); } void hide_me() {} }; struct derived : base<derived> { void hide_me() { /* do something else */ } }; I have a lot of these hideable functions, and different types of T need to hide different functions. In this situation, it would be more efficient to simply not do the prepare() or finalize() stage if these functions are not implemented in the derived type. So I'd like to find a way to detect if a function is hidden or not, in a way that works at compile-time so that I can use it with templates to prevent the prepare() or finalize() code from even being instantiated. Does anyone have any ideas? -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Juan Pedro Bolivar Puente on 16 Feb 2010 07:34 This might help: http://lists.boost.org/Archives/boost/2002/03/27251.php You can simplify the pattern a little bit by directly using the SFINAE in the do_something() function. JP On 16/02/10 08:09, Cory Nelson wrote: > > I am using CRTP (the Curiously Recurring Template Pattern) like so: > > template<T> > struct base > { > void do_something() > { > prepare(); > static_cast<T*>(this)->hide_me(); > finalize(); > } > > void hide_me() {} > }; > > struct derived : base<derived> > { > void hide_me() { /* do something else */ } > }; > > I have a lot of these hideable functions, and different types of T > need to hide different functions. In this situation, it would be more > efficient to simply not do the prepare() or finalize() stage if these > functions are not implemented in the derived type. > > So I'd like to find a way to detect if a function is hidden or not, in > a way that works at compile-time so that I can use it with templates > to prevent the prepare() or finalize() code from even being > instantiated. Does anyone have any ideas? -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Maxim Yegorushkin on 16 Feb 2010 07:41
On Feb 16, 6:09 am, Cory Nelson <phro...(a)gmail.com> wrote: > Hello all, > > I am using CRTP (the Curiously Recurring Template Pattern) like so: > > template<T> > struct base > { > void do_something() > { > prepare(); > static_cast<T*>(this)->hide_me(); > finalize(); > } > > void hide_me() {} > > }; > > struct derived : base<derived> > { > void hide_me() { /* do something else */ } > > }; > > I have a lot of these hideable functions, and different types of T > need to hide different functions. In this situation, it would be more > efficient to simply not do the prepare() or finalize() stage if these > functions are not implemented in the derived type. > > So I'd like to find a way to detect if a function is hidden or not, in > a way that works at compile-time so that I can use it with templates > to prevent the prepare() or finalize() code from even being > instantiated. Does anyone have any ideas? You can benefit from the fact, that if derived does override base::hide_me(), than expression &T::hide_me yields an r-value of type void(T::*)(), otherwise it is void(base::*)(): [max(a)truth test]$ /home/max/depot1/infra/prj_ledger_dev/build/Linux- x86_64-64.g++-debug/test/test void base<T>::really_do_something(void (T::*)()) [with T = derived] T overrides hide_me void base<T>::really_do_something(void (base<T>::*)()) [with T = derived2] T doesn't override hide_me [max(a)truth test]$ [max(a)truth test]$ [max(a)truth test]$ [max(a)truth test]$ cat test.cc #include <stdio.h> template<class T> struct base { void do_something() { this->really_do_something(&T::hide_me); } void hide_me() { } private: void prepare() {} void finalize() {} void really_do_something(void(base::*)()) { printf("%s\nT doesn't override hide_me\n", __PRETTY_FUNCTION__); } void really_do_something(void(T::*)()) { printf("%s\nT overrides hide_me\n", __PRETTY_FUNCTION__); prepare(); static_cast<T*>(this)->hide_me(); finalize(); } }; struct derived : base<derived> { void hide_me() {} }; struct derived2 : base<derived2> {}; int main() { derived().do_something(); printf("\n"); derived2().do_something(); } [max(a)truth test]$ g++ -Wall -o test test.cc [max(a)truth test]$ ./test void base<T>::really_do_something(void (T::*)()) [with T = derived] T overrides hide_me void base<T>::really_do_something(void (base<T>::*)()) [with T = derived2] T doesn't override hide_me -- Max -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |