- Refactoring dilemma - 4 Updates
- Problem with (simple) use of templates - 8 Updates
- RAII design question - 2 Updates
- Problem with (simple) use of templates - 1 Update
- Const on pass-by-value formal args (was: Template type deduction from value for class templates and value templates) - 1 Update
woodbrian77@gmail.com: Jun 27 11:32AM -0700 Shalom In an edit to this post: https://codereview.stackexchange.com/questions/166573/messaging-and-serialization-library , I added links to both versions of the code. Would someone take a look and let me know what they think? Brian Ebenezer Enterprises - Enjoying programming again. http://webEbenezer.net |
"Öö Tiib" <ootiib@hot.ee>: Jun 27 01:27PM -0700 > https://codereview.stackexchange.com/questions/166573/messaging-and-serialization-library > , I added links to both versions of the code. Would someone take a look and > let me know what they think? You want code review? From afar looks fine. Closer look reveals too lot of function overloads named "Marshal" for my taste. Correctness I can't evaluate without knowing requirements to your code. I also do not have actual data to profile your code. Everything being named "Marshal" would likely make profiling more annoying than usual. What else you would like to know? |
woodbrian77@gmail.com: Jun 27 02:43PM -0700 On Tuesday, June 27, 2017 at 3:27:53 PM UTC-5, Öö Tiib wrote: > Correctness I can't evaluate without knowing requirements to your code. > I also do not have actual data to profile your code. Everything being > named "Marshal" would likely make profiling more annoying than usual. In the original version there are six functions called "Marshal". I think this is a tame use of overloading. > What else you would like to know? I'm not sure whether to stick with the version that's more verbose, but that compilers tolerate better, or to switch to the version that uses variadics. From a code generation perspective, I'd like to use the variadics version as it's easier to generate since it's less verbose. But if compilers aren't ready for it, it may be pushing things too much. Brian Ebenezer Enterprises - In G-d we trust. http://webEbenezer.net |
"Öö Tiib" <ootiib@hot.ee>: Jun 27 03:11PM -0700 > From a code generation perspective, I'd like to use the variadics > version as it's easier to generate since it's less verbose. But if > compilers aren't ready for it, it may be pushing things too much. When you are not sure what is better then it can be that neither is better. For example it can be different per project what is better. On such cases it may make sense to add optional choice. |
scott.a.mayo@gmail.com: Jun 27 09:05AM -0700 I'm checking to see if my understanding of C++ is correct. I've run into problems compiling code under g++ and I'm trying to decide if the problem is mine or g++'s. This wasn't supposed to be complicated... In a header, I have a templated class as a parent class. Relevant excerpts: template<int Size_> class Buffer { public: ..... bool overflowed_; //public ....}; //And then I want to base off it with: template<int Size_> class OutputBuffer : public Buffer<Size_> { public: .... OutputBuffer() : Buffer<Size_>() { } .... void doSomething() { if (overflowed_) {....} } //problems! }; This looks straightforward to me. But for g++ at least, overflowed_, and every other reference to any function or data in Buffer, apparently needs to be qualified with Buffer<Size_>::. This seems especially odd for overflowed_, which doesn't participate in the parameterization of the parent's template. But that shouldn't matter. It's a parent class with public members and it should not matter that it's also templated. Note the compile isn't failing on an instantiation. It fails as soon as the compiler parses the header, before any instantiation is attempted. This makes no sense to me. OutputBuffer is based on a type, and the type is specified by the parent class syntax " : public Buffer<Size_>". When the time comes to instantiate, that parent class will have a definitive definition, but even before that, it seems to be that C++ specifies that the compiler has enough visibility into the subclass to know exactly what I'm referring to. The parent class should be "specified enough" at that point. Other compilers have accepted this, so now I'm trying to determine if this is my problem or g++'s. I can work around it by adding Buffer<Size_>:: everywhere, but that's not how subclassing is supposed to work. (Note I can't avoid g++ - eventually this code is going to a platform where it's likely g++ or nothing.) Insight into why C++ doesn't promise what I want, is welcome. This has messed with my understanding of how templates work. |
Paavo Helde <myfirstname@osa.pri.ee>: Jun 27 08:15PM +0300 > void doSomething() { if (overflowed_) {....} } //problems! > }; > This looks straightforward to me. But for g++ at least, overflowed_, and every other reference to any function or data in Buffer, apparently needs to be qualified with Buffer<Size_>::. This seems especially odd for overflowed_, which doesn't participate in the parameterization of the parent's template. But that shouldn't matter. It's a parent class with public members and it should not matter that it's also templated. The idiomatic way to fix this is: void doSomething() { if (this->overflowed_) {....} } See https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-members In short, there is no problem with gcc here, but there is a problem with either your code or possibly with the C++ standard itself if the FAQ needs to contain such usage warnings as "This might hurt your head!" |
"Öö Tiib" <ootiib@hot.ee>: Jun 27 10:47AM -0700 On Tuesday, 27 June 2017 20:15:29 UTC+3, Paavo Helde wrote: > > This looks straightforward to me. But for g++ at least, overflowed_, and every other reference to any function or data in Buffer, apparently needs to be qualified with Buffer<Size_>::. This seems especially odd for overflowed_, which doesn't participate in the parameterization of the parent's template. But that shouldn't matter. It's a parent class with public members and it should not matter that it's also templated. > The idiomatic way to fix this is: > void doSomething() { if (this->overflowed_) {....} } Other way to fix this is to bring the member into scope: using Buffer<Size_>::overflowed_; void doSomething() { if (overflowed_) {....} } > In short, there is no problem with gcc here, but there is a problem with > either your code or possibly with the C++ standard itself if the FAQ > needs to contain such usage warnings as "This might hurt your head!" Simpler is just to live with yet another gotcha that standard requires name overflowed_ to be looked-up in a base classes, but not in dependent templates of base classes and to hope that it makes life easier for compiler-makers somehow. |
scott.a.mayo@gmail.com: Jun 27 10:51AM -0700 On Tuesday, June 27, 2017 at 1:15:29 PM UTC-4, Paavo Helde wrote: ... > In short, there is no problem with gcc here, but there is a problem with > either your code or possibly with the C++ standard itself if the FAQ > needs to contain such usage warnings as "This might hurt your head!" Wow. Yes it worked. I've never come across a situation where this-> was required anywhere. Live and learn, thanks. |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jun 27 08:02PM +0200 > parameterization of the parent's template. But that shouldn't matter. > It's a parent class with public members and it should not matter that > it's also templated. It matters because the `Buffer` class can be specialized for some template parameter values, and those specialization will not necessarily have the `overflowed_` member, or whatever. We say that these expressions /depend/ on the template parameters. A good way to deal with it is to add using Base = Buffer<Size_>; using Base::overflowed_; Or you can qualify each usage, which is at odds with the principle of not repeating yourself needlessly. Visual C++ is more lenient because it follows the pre-standard single phase template parsing rules (disclaimer: I no longer remember the details of this, I'd have to look it up). I.e. g++ is more conforming and hence, IMO., more impractical. For I can't remember any single occasion where this required nonsense verbosity has saved my code from being incompatible with a nasty specialization of a base class template. > [snip] Cheers & hth., - Alf |
scott@slp53.sl.home (Scott Lurndal): Jun 27 06:08PM >> either your code or possibly with the C++ standard itself if the FAQ >> needs to contain such usage warnings as "This might hurt your head!" >Wow. Yes it worked. I've never come across a situation where this-> was required anywhere. Live and learn, thanks. Another place where this-> is required is with member function pointers: e.g. bool (c_processor::*op_insn)(struct _op *); ... // Process the instruction failed = (this->*opp->op_insn)(opp); |
legalize+jeeves@mail.xmission.com (Richard): Jun 27 07:18PM [Please do not mail me a copy of your followup] "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> spake the secret code > using Base::overflowed_; >Or you can qualify each usage, which is at odds with the principle of >not repeating yourself needlessly. I like this as the minimal change needed to resolve the problem. Can we do better? What if we move everything that isn't dependent on the template parameters into a separate base class? This would be a base class of Buffer<N>: class BufferBase { public: bool overflowed_; // ... }; template <int Size_> class Buffer : public BufferBase { // ... }; I like this better because it disambiguates the references to overflowed_ without any using statements in derived classes. It also clearly separates everything that depends on template parameters from everything that doesn't which I think makes for a cleaner design. -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Terminals Wiki <http://terminals-wiki.org> The Computer Graphics Museum <http://computergraphicsmuseum.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
legalize+jeeves@mail.xmission.com (Richard): Jun 27 07:18PM [Please do not mail me a copy of your followup] scott.a.mayo@gmail.com spake the secret code >Wow. Yes it worked. I've never come across a situation where this-> was >required anywhere. Live and learn, thanks. It isn't required, it is simply one way (of several) to resolve the ambiguity. -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Terminals Wiki <http://terminals-wiki.org> The Computer Graphics Museum <http://computergraphicsmuseum.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
"Öö Tiib" <ootiib@hot.ee>: Jun 26 11:28PM -0700 On Tuesday, 27 June 2017 00:36:09 UTC+3, Real Troll wrote: > Either you meant: gullible > or you meant: quibble > Which is it Andy? It is just a play with words. Behaving immature and silly may amuse but does not unfortunately bring childhood back. |
scott.a.mayo@gmail.com: Jun 27 09:17AM -0700 On Monday, June 12, 2017 at 4:59:10 PM UTC-4, gwowen wrote: > CancellableTimer IS A Timer, so it'd be nice if I could extend Timer in > this way. > What am I missing? Ignoring all the discussion of LSP this and quibble that, you've already worked out that the destructor in the base class runs regardless. What you're missing is that subclasses generally restrict behaviour, they don't extend it. (That's an exaggeration, but it holds in this case.) Your base class should be CancellableTimer; and if you want a Timer that can't be accidentally cancelled (which you reasonably might), make a subclass that hides the cancellation mechanism. Virtual functions will help. |
ram@zedat.fu-berlin.de (Stefan Ram): Jun 27 04:15PM >overflowed_, and every other reference to any function or >data in Buffer, apparently needs to be qualified with >Buffer<Size_>:: struct board_type : public ::std::vector< position_type > { using ::std::vector< position_type >::vector; |
Jorgen Grahn <grahn+nntp@snipabacken.se>: Jun 27 11:19AM On Mon, 2017-06-12, Adam Badura wrote: >> interface, it doesn't matter at all to a caller, and so the C++ rules >> make the following two declarations exactly equivalent, denoting the >> same function, with the same function type: ... > (declaration split from definition) you skip the const on > declaration and have it on definition only? Or for the consistency > you have it always? "A foolish consistency is the hobgoblin of little minds." I prefer to have the const only where it carries meaning: void foo(int n); void foo(const int n) { ... } I think that's how most people do it. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
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