- Ah - 5 Updates
- In template class, temporaries are substituted for const ref arguments -- trying to diagnose why this causes a crash. - 5 Updates
- Concatenating strings efficiently - 3 Updates
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Oct 21 08:56AM +0200 #include <iostream> template< class Item > auto operator,( std::ostream& stream, const Item& item ) -> std::ostream& { return (stream << item); } auto main() -> int { using namespace std; cout << "Did you know, 6*7 = ", 6*7, "! :)\n"; } Cheers!, - ALf |
Ralf Goertz <me@myprovider.invalid>: Oct 21 10:58AM +0200 Am Sun, 21 Oct 2018 08:56:52 +0200 > } > Cheers!, > - ALf Nice. But the output Did you know, 6*7 = 42! :) is false since 42! =1405006117752879898543142606244511569936384000000000 SCNR |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Oct 21 05:34PM +0100 On 21/10/2018 07:56, Alf P. Steinbach wrote: > } > Cheers!, > - ALf Egregious for various reasons. /Flibble -- "You won't burn in hell. But be nice anyway." – Ricky Gervais "I see Atheists are fighting and killing each other again, over who doesn't believe in any God the most. Oh, no..wait.. that never happens." – Ricky Gervais "Suppose it's all true, and you walk up to the pearly gates, and are confronted by God," Bryne asked on his show The Meaning of Life. "What will Stephen Fry say to him, her, or it?" "I'd say, bone cancer in children? What's that about?" Fry replied. "How dare you? How dare you create a world to which there is such misery that is not our fault. It's not right, it's utterly, utterly evil." "Why should I respect a capricious, mean-minded, stupid God who creates a world that is so full of injustice and pain. That's what I would say." |
woodbrian77@gmail.com: Oct 21 09:52AM -0700 On Sunday, October 21, 2018 at 1:57:03 AM UTC-5, Alf P. Steinbach wrote: > #include <iostream> > template< class Item > > auto operator,( std::ostream& stream, const Item& item ) I suggest you add a space after function/operator names. Brian Ebenezer Enterprises - Enjoying programming again https://github.com/Ebenezer-group/onwards |
Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo>: Oct 21 07:01PM -0400 Alf P. Steinbach wrote: > } > Cheers!, > - ALf I use this trick in one of my logging libraries before variadic templates became available, something to the form log(logRecord, "did you know", ...); `log' does actual formatting and flushing, `logRecord' just collects a list of loggable items to include into the log record. This way you never forget to flush the log and you can pass a log record to a function that does not necessarily logs by that saving you unnecessary formatting (handy when you only want to work on error). my 2c -Pavel |
Sam <sam@email-scan.com>: Oct 21 08:28AM -0400 Paul writes: > AndSpecification(const Specification<T>& first, const Specification<T>& > second) > : first(first), second(second) {} You're grabbing references to these parameters and storing them in this (template) class. > auto spec2 = SizeSpecification(Size::large)&& > ColorSpecification(Color::green); You are constructing an instance of the AndSpecification template, using the && operator overload. Both "SizeSpecification(Size::large)" and "ColorSpecification(Color::green)" are temporary objects here, that get created when evaluating this expression. And immediately destroyed after the expression gets evaluated. Your instance of the AndSpecification template, thusly, ends up having references to destroyed objects. They certainly exist when AndSpecification gets constructured, and its constructor gets valid references to them. But because the referenced objects are temporary objects, they get destroyed soon thereafter. Explicitly instantiating everything should work: auto large=SizeSpecification(Size::large); auto green=SizeSpecification(Size::green); auto spec2 = large && green; Now, both large and green objects will exist as long as the "spec2" object exists, so the references to them, in spec2, remain valid. Of course, this is not as convenient. But this is how your templates are designed. Basically, if you store a reference somewhere, it's your responsibility to make sure that the referenced objects still exist every time you use that referenced object. C++ will not do it for you. The only way to make sure that the object exist is store the object itself, and not a reference to it. This is impossible to do, in your situation, because the object themselves are abstract base classes. The most common way this kind of concept gets implemented is with smart pointers. And plenty of overloading. |
Jorgen Grahn <grahn+nntp@snipabacken.se>: Oct 21 02:37PM On Sun, 2018-10-21, Sam wrote: >> or something. >> Please could someone explain exactly what the problem is? >> Thank you. (snip detailed explanation) > because the object themselves are abstract base classes. > The most common way this kind of concept gets implemented is with smart > pointers. And plenty of overloading. For perspective, I note that it's all massive overkill in this specific case, which is about finding the large, green objects in a sequence. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
Jorgen Grahn <grahn+nntp@snipabacken.se>: Oct 21 02:41PM On Sat, 2018-10-20, Paul wrote: > or something. > Please could someone explain exactly what the problem is? > Thank you. ... > Product tree{"Tree", Color::green, Size::large}; > Product house{"House", Color::blue, Size::large}; > const vector<Product*> all { &apple, &tree, &house }; Unrelated to your problem, I suppose, but avoid storing pointer in containers, when you can store the objects themselves: const vector<Product> all { {"Apple", Color::green, Size::small}, {"Tree", Color::green, Size::large}, {"House", Color::blue, Size::large}, }; /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
Paul <pepstein5@gmail.com>: Oct 21 08:12AM -0700 On Sunday, October 21, 2018 at 3:41:38 PM UTC+1, Jorgen Grahn wrote: > {"Tree", Color::green, Size::large}, > {"House", Color::blue, Size::large}, > }; These are dummy examples for the purposes of learning good technique. I thought that, assuming a real-world example where the Product struct would be much more complicated, then storing pointers saves memory. Am I wrong? Thanks a lot for your help, Paul |
Jorgen Grahn <grahn+nntp@snipabacken.se>: Oct 21 06:58PM On Sun, 2018-10-21, Paul wrote: >> {"House", Color::blue, Size::large}, >> }; > These are dummy examples for the purposes of learning good technique. As you may have sensed already ;-) I have issues with that strategy. I understand that learning techniques is necessary, eventually. But picking simple (yet synthetic) examples and applying advanced solutions may teach you to overdesign things which should be simple. A technique is only good in a context where it's fitting. > I thought that, assuming a real-world example where the Product struct > would be much more complicated, then storing pointers saves memory. > Am I wrong? Yes. Why would it save memory? Nowadays it doesn't even avoid a copy, since you can construct the Product straight into the std::vector<Product>. The generic name "Product" made me think you eventually meant to have it as a base class and derive Apple, Tree and House from it. In that case you couldn't have a std::vector<Product>, and storing pointers would be one solution. Even then, I think people would recommend a vector of smart pointers instead. (On the other hand, I don't think that would be a very realistic class hierarchy. If you see everything as a product, you don't care if it's an apple, and it won't have any apple-specific behavior. You may care if a products can be shipped to Australia, can be frozen or be stored for a year instead.) /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Oct 21 01:53AM +0200 On 20.10.2018 20:45, Manfred wrote: > *outIt++ = OutputIterator::traits_type::to_char_type('0' + d.rem); > } > } The C++ standard guarantees that the decimal digits are consecutive. There's no such guarantee for the English letters. Since I like things simple and robust I don't like this function: it relies too much on client code supplying a safe output iterator, and the recursive call will most probably not be optimized out, so, inefficient. But then I don't like the C++17 standard library solution either, the `std::to_chars` function (https://en.cppreference.com/w/cpp/utility/to_chars). They boast that "std::to_chars is locale-independent, non-allocating, and non-throwing". But that's basic requirements. In particular there is apparently no way to compute a required buffer size. If so then that's kind of über-silly. IMHO. When the time comes where all common compilers support `std::to_chars` one can write some simple wrappers. Maybe that time has already come, a month or two ago. Not sure, I haven't checked. Cheers!, - Alf |
Manfred <noname@add.invalid>: Oct 21 05:26PM +0200 On 10/21/2018 1:53 AM, Alf P. Steinbach wrote: >> } >> } > The C++ standard guarantees that the decimal digits are consecutive. Good remark, thanks! > Since I like things simple and robust I don't like this function: it > relies too much on client code supplying a safe output iterator, and the > recursive call will most probably not be optimized out, so, inefficient. In fact in all of the code I posted there is absolutely no error checking - which makes it inapt for anything else than a post example. I believe the recursive call cannot be optimized out, since output must occur /after/ the recursion. This is a direct consequence that the digits have to be output in reverse order with respect to the div() sequence. In this respect I am not sure it is /that/ inefficient, it basically replaces allocation of a (possibly growing) string buffer with a call sequence on the stack. I guess in general the latter is more efficient than the former. There are most probably better solutions, though.. |
Manfred <noname@add.invalid>: Oct 21 06:19PM +0200 On 10/21/2018 12:11 AM, Pavel wrote: > Neat solution, BTW. I like your recursive encodeDecimal, very haskellish. There > is no need to compare inIt to endIt more than once though. Yes, nor there is need to dereference inIt more than once, so that a couple of local variables would be in order. Also, an option could be to have encodeDecimal as a recursive lambda. |
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