Saturday, February 13, 2016

Digest for comp.lang.c++@googlegroups.com - 8 updates in 5 topics

ram@zedat.fu-berlin.de (Stefan Ram): Feb 13 03:02PM

>We often are in situation where base class needs to call functions of
>derived class. Majority of other programming languages have chosen to
>use virtual functions always in such a situation but C++ has CRTP.
¯¯¯¯¯¯
There also is the Pattern »delegation« to allow this.
Many Java programmers, for example, prefer delegation
to inheritance.
"Öö Tiib" <ootiib@hot.ee>: Feb 13 06:29AM -0800

On Thursday, 11 February 2016 19:28:58 UTC+2, K. Frank wrote:
> discussions where the CRTP (curiously recurring
> template pattern) is used, as I understand it, to
> define interfaces.
 
We often are in situation where base class needs to call functions of
derived class. Majority of other programming languages have chosen to
use virtual functions always in such a situation but C++ has CRTP.
 
CRTP provides two clear strengths, one is better efficiency and other
is faster feedback (compile time) about defects. It also provides
a major meta-weakness by increasing complexity of design since choice has
to be made design-time.
 
The choice between virtual functions or CRTP depends on if the
interrelations between run-time objects of resulting program are fixed
and known compile-time or not. On lot of cases these very likely are, on
few cases these certainly are not and on significant amount of cases it
can be uncertain design-time.
 
Therefore usage of virtual functions may be a premature pessimization
or usage of CRTP may be a premature optimization and if it happens
often then developer needs to gain skill in thinking about it first or
in refactoring between the two. ;)
 
> the interface to the implementation:
 
> void doA() { static_cast<D*>(this)->implementationA(); }
 
> seems annoying.
 
Unless I misunderstand you it looks rather little semantic
inconvenience that can be reduced with little mixin that provides
convenience helper overloads for that if you really bother.
 
void a() const { md().do_a(); }
 
Replace 'md()' with 'most_derived()' if abbreviations are forbidden
by codding standard.
 
Note that some developers ignore encapsulation and const-correctness
(use 'struct', everything non-const) and copy-paste code and that
results with wrong template arguments of CRTP:
 
struct foo : base<bar> { /* ... */ };
 
It is good idea to make that not to compile for example by making
something of 'base<bar>' non-accessible to 'foo' and idiomatically
it is private destructor:

template <typename T>
struct base
{
private:
~base() {}
friend T;
};
 
Note also that on lot of cases we want to do more things in implementation.
It may be for debugging purposes or because the gaps that derived class
fills do not match with external interface exactly 1:1:
 
void a() const { DBG("transaction a"); md().check(); md().do_a(); }
void b() { prepare_b(); md().do_b(); }
 
 
 
> and use it, e.g.:
 
> UseInterface<C> uc;
> uc.doStuff;
 
That is useful on lucky case when interface and gaps to fill match
exactly 1:1. The convenient external interface and gaps that derived
class is anticipated potentially to fill are usually rather different
and so your way results with violation of DRY (IOW several of
copy-paste-filled classes).
 
> CRTP to define interfaces? If not, do you think that
> using the CRTP as a place to define an interface is
> worth the hassle?
 
I think that you consider the problem that CRTP solves as some sort of
close to 1:1 thin interface wrapper, and that is not anywhere frequent
case. You will get better idea what CRTP does by reading documentation
of libraries that use it in interface. There is large amount of
such libraries since the CRTP typically wins dynamic polymorphism in
performance and gives more compile-time diagnostics on case of misuse.
 
For example documentation of boost::iterator_facade explains it
quite well what is really typically expected to be going on:
 
|> iterator_facade and the operator implementations need to be able to
|> access the core member functions in the derived class. Making the
|> core member functions public would expose an implementation detail to
|> the user. The design used here ensures that implementation details
|> do not appear in the public interface of the derived iterator type.
http://www.boost.org/doc/libs/1_52_0/libs/iterator/doc/iterator_facade.html
Christopher Pisz <nospam@notanaddress.com>: Feb 12 06:24PM -0600


>> ermehgerd, it's killing me.
 
> <snip>
 
> "ermehgerd"? What is that? Even the mighty Google can't help me.
 
Google shows me this:
http://cosmouk.cdnds.net/15/43/980x490/landscape-1445262691-970.jpg
 
--
I have chosen to troll filter/ignore all subthreads containing the
words: "Rick C. Hodgins", "Flibble", and "Islam"
So, I won't be able to see or respond to any such messages
---
Christopher Pisz <nospam@notanaddress.com>: Feb 12 06:25PM -0600


>> ermehgerd, it's killing me.
 
> <snip>
 
> "ermehgerd"? What is that? Even the mighty Google can't help me.
 
Alternatively, you may use this
http://ermahgerd.jmillerdesign.com/#!/translate
 
 
--
I have chosen to troll filter/ignore all subthreads containing the
words: "Rick C. Hodgins", "Flibble", and "Islam"
So, I won't be able to see or respond to any such messages
---
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Feb 13 12:29AM

On 13/02/2016 00:24, Christopher Pisz wrote:
 
>> "ermehgerd"? What is that? Even the mighty Google can't help me.
 
> Google shows me this:
> http://cosmouk.cdnds.net/15/43/980x490/landscape-1445262691-970.jpg
 
Oh my fucking God?
 
/Flibble
Christopher Pisz <nospam@notanaddress.com>: Feb 12 06:42PM -0600

On 2/12/2016 1:11 PM, Daniel wrote:
> json events, and an XPATH validator that can receive SAX events, that could
> be a practical solution.
 
> Daniel
 
I will check it out. Thank you sir.
 
--
I have chosen to troll filter/ignore all subthreads containing the
words: "Rick C. Hodgins", "Flibble", and "Islam"
So, I won't be able to see or respond to any such messages
---
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Feb 12 11:51PM

On 12/02/2016 19:43, Ian Collins wrote:
> https://www.youtube.com/watch?v=JaY7VTftPdY
 
Best. YouTube. Video. Ever.
 
/Flibble
"Hans Bos" <hans.bos@xelion.nl>: Feb 12 11:53PM +0100

"Cholo Lennon" <chololennon@hotmail.com> wrote in message
news:n9kjjo$62s$1@gioia.aioe.org...
 
 
...
> provide a synchronous access to data). Another advantage over public data
> members is that calls to them can be deferred in time with
> std::function/std::bind.
 
You can use std::function and std::bind with data members as well since they
are defined in terms of INVOKE (or std::invoke).
You can call std::invoke with a pointer to member and an object pointer.
 
Greetings,
Hans.
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: