From: Cory Nelson on
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
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
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! ]