- The CRTP for interfaces -- not so useful? - 1 Update
- The CRTP for interfaces -- not so useful? - 1 Update
- json path in C++ - 4 Updates
- Swearing not considered harmful... - 1 Update
- A replacement for getters/setters ? - 1 Update
| 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:
Post a Comment