Tim Rentsch <tr.17687@z991.linuxsc.com>: Nov 08 11:17PM -0800 > a single instantiation). > My context is C++11 or C++14; a C++17 or later solution would be > interesting, but of no immediate use to me. I believe C++17 (or C++20?) offers constructions sufficient to accomplish this. However I don't think any of those ways are available in C++14 or earlier. If I had this problem to deal with, probably I would do something like this: #include <unordered_set> #include <unordered_map> #define CLASS_HASHER( KeyType ) \ namespace std { \ template <> struct hash< class KeyType > { \ \ using result_type = size_t; \ using argument_type = KeyType; \ \ result_type \ operator()( const KeyType &it ) const { \ return it.me_hash_function(); \ } \ \ }; \ } struct Whatsit { size_t blah; size_t me_hash_function() const { return blah; } }; CLASS_HASHER( Whatsit ) void check_it_out(){ std::unordered_map< Whatsit, int > whatsits_values; std::unordered_set< Whatsit > whatsits; } Of course the point of the CLASS_HASHER macro is that it can be reused for any class that needs it. The overhead is then one extra line of code per self-hashing class, which in my view is acceptable. |
Jorgen Grahn <grahn+nntp@snipabacken.se>: Nov 09 08:37PM On Mon, 2020-11-09, Tim Rentsch wrote: > reused for any class that needs it. The overhead is then one > extra line of code per self-hashing class, which in my view > is acceptable. Thanks. Yes, an extra line would be acceptable -- although I'm sure people would find the macro odd, if they found it. For now I've decided to use std::map and friends, unless I know I have a performance problem. I'm a bit disappointed, because C++ doesn't usually let me down. When things are hard to express well, I normally understand why ... but I still don't understand why it's harder to use a class with the unordered containers than with the ordered equivalents. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
"Christian Hanné" <the.hanne@gmail.com>: Nov 09 09:03AM +0100 >> Designated initializers aren't needed. There are constructors. > Loops aren't needed. There are gotos. That's an analogy in the opposite direction. Gotos are technically less usable than loops. But constructors are more flexible than designated initializers. |
Juha Nieminen <nospam@thanks.invalid>: Nov 09 08:14AM > Designated initializers aren't needed. There are constructors. Show me how you do this with constructors: struct S { int a = 1, b = 2, c = 3, d = 4, e = 5; }; const S obj1 = { .b = 10, .d = 20 }; const S obj2 = { .d = 15, .e = 16 }; const S obj3 = { .a = 100, .c = 200, .e = 300 }; |
"Christian Hanné" <the.hanne@gmail.com>: Nov 09 09:19AM +0100 > const S obj1 = { .b = 10, .d = 20 }; > const S obj2 = { .d = 15, .e = 16 }; > const S obj3 = { .a = 100, .c = 200, .e = 300 }; That's not possible and not needed. But the default-values make a lot of confusion since they can be scattered in the defininition of the struct. So better use constructors. |
Ian Collins <ian-news@hotmail.com>: Nov 09 09:29PM +1300 On 09/11/2020 21:19, Christian Hanné wrote: >> const S obj2 = { .d = 15, .e = 16 }; >> const S obj3 = { .a = 100, .c = 200, .e = 300 }; > That's not possible and not needed. Why not needed? > But the default-values make a lot of confusion since > they can be scattered in the defininition of the struct. No, they don't. > So better use constructors. No, it isn't. If you need different members initialised in different contexts, designated initialisers are your friend. -- Ian. |
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Nov 09 12:39AM -0800 >> So better use constructors. > No, it isn't. If you need different members initialised in different > contexts, designated initialisers are your friend. A while ago, Christian Hanné posted a lot of deliberate nonsense in comp.lang.c. Don't expect reasonable replies. -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com Working, but not speaking, for Philips Healthcare void Void(void) { Void(); } /* The recursive call of the void */ |
"Christian Hanné" <the.hanne@gmail.com>: Nov 09 09:50AM +0100 >> So better use constructors. > No, it isn't. If you need different members initialised in different > contexts, designated initialisers are your friend. I said why this confuses the reader. With constructors you have the declaration of the construtor in a tooltip in your IDE, with designated initializers you have to check the structure definition first. |
"Christian Hanné" <the.hanne@gmail.com>: Nov 09 09:50AM +0100 > A while ago, Christian Hanné posted a lot of deliberate > nonsense in comp.lang.c. Don't expect reasonable replies. I never posted nonsense. |
Juha Nieminen <nospam@thanks.invalid>: Nov 09 11:46AM > the declaration of the construtor in a tooltip in your IDE, with > designated initializers you have to check the structure definition > first. Firstly, if understanding the code requires an IDE, then the code is badly designed. Secondly, if an IDE is able to show the constructor signature in a tooltip, then certainly it can show the members of a struct in a designated initalizer list? If not, and you rely so much on IDE tooltips, then get a better IDE. Thirdly, designated initializers make initialization a lot clearer because they function, essentially, as named parameters, which is something that constructors (and functions in general) have always lacked in C++. This is particularly handy for configuration headers and such, which may be written and fine-tuned by team members other than the original programmer (some of which may not be programmers at all). I have used this quite extensively, to create "configuration" files like: const Settings kSettings { .numberOfStuff = 123, .aValueForSomething = 5, .aFactorUsedForThis = 0.25, .elements = { { .amount = 5, .factor = 2.2, .seconds = 10 }, { .amount = 8, .factor = 1.0, .seconds = 15 }, { .amount = 1, .factor = 0.5, .seconds = 5 } } }; Even a complete non-coder can go and fine-tune those values without the need to understand C++ (especially when the variables are named clearly according to the context; obviously I used fictitious names above). (In fact, I have used that technique quite a lot in some Objective-C++ programs, where the order of initialization doesn't need to match the order of declaration. This is particularly handy because it allows the initialization to use an ordering that's easy to read and understand, while the declaration may use an ordering that's eg. optimized for space, as the order of declaration of member variables matter in this regard. It's a huge same that C++20 decided to put the limitation that the initializers must be in the same order as the declaration.) |
"Christian Hanné" <the.hanne@gmail.com>: Nov 09 12:50PM +0100 > Firstly, if understanding the code requires an IDE, then the code is badly > designed. Wrong, an IDE has many facilities which can't be replaced by proper coding. > Secondly, if an IDE is able to show the constructor signature in a tooltip, > then certainly it can show the members of a struct in a designated > initalizer list? ... Neither CLion, nor Visual Studio, nor Eclipse CDE can do this. > because they function, essentially, as named parameters, which is > something that constructors (and functions in general) have always > lacked in C++. Therefore you have an IDE. Haven't read the rest of your nonsense. |
Juha Nieminen <nospam@thanks.invalid>: Nov 09 02:32PM > Haven't read the rest of your nonsense. I'll take that as a concession of defeat. If you can't answer to the arguments given to you, that's because you don't have an answer. You don't have any valid counter-argument. Therefore you just concede. The only thing you can do at that point is act in an arrogant and dismissive manner. I suppose the insults will soon follow. |
"Christian Hanné" <the.hanne@gmail.com>: Nov 09 03:43PM +0100 > don't have any valid counter-argument. Therefore you just concede. > The only thing you can do at that point is act in an arrogant and > dismissive manner. I suppose the insults will soon follow. Why do you argue so if you do it the same way by not responding to what I said ? |
Juha Nieminen <nospam@thanks.invalid>: Nov 09 03:41PM >> dismissive manner. I suppose the insults will soon follow. > Why do you argue so if you do it the same way by not responding to > what I said ? You didn't bother responding to all the arguments I made, but you expect me to respond to all your arguments? Especially when you have that kind of attitude? Right. |
scott@slp53.sl.home (Scott Lurndal): Nov 09 04:09PM >don't have any valid counter-argument. Therefore you just concede. >The only thing you can do at that point is act in an arrogant and >dismissive manner. I suppose the insults will soon follow. You are responding to Bonita (who, when slips and forgets to delete the attribution headers, shows that Bonita uses a German locale in its newsreader). Note this Hanne fellow also removes attributions and makes stupid arguments. |
"Christian Hanné" <the.hanne@gmail.com>: Nov 09 06:31PM +0100 > You are responding to Bonita (who, when slips and forgets to > delete the attribution headers, shows that Bonita uses a > German locale in its newsreader). Sorry, but please stop with this imputations. |
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Nov 09 10:47AM -0800 > German locale in its newsreader). > Note this Hanne fellow also removes attributions and makes stupid > arguments. I don't know whether Christian Hanné is a sockpuppet for Bonita or not. And frankly it doesn't matter. I suggest we avoid wasting time debating that particular point. (I personally will not waste time responding to Christian Hanné at all.) -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com Working, but not speaking, for Philips Healthcare void Void(void) { Void(); } /* The recursive call of the void */ |
Jorgen Grahn <grahn+nntp@snipabacken.se>: Nov 09 08:24PM On Sun, 2020-11-08, Christian Hanné wrote: > Designated initializers aren't needed. There are constructors. To my surprise, I agree. In fact, I thought everyone agreed on this, and that that's why it wasn't squeezed into C++11. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
olcott <NoOne@NoWhere.com>: Nov 09 09:00AM -0600 This <is> the simplest concrete counter-example of all of the conventional halting problem proofs. void Halt_Fooler(u32 P) { if (Halts(P, P)) HALT else HERE: goto HERE; } I am dropping my reference to Linz because it only gets people confused. The UTM Halts(u32 P, u32 I) (at least partial) halt decider executes the x86 Turing machine Description of its input until it detects that: (a) Its input would never terminate unless forced to terminate by this (at least partial) halt decider. (b) Its input has already halted on its own. When-so-ever a halt decider correctly decides that its input would never halt unless forced to halt by this halt decider this halt decider has correctly detected an input that would not halt and can transition to its final state of DOES_NOT_HALT. This shows that H_HAT(H_HAT) does not halt when run on its own: bool Aborted_Because_Non_Halting_Behavior_Detected(u32 P, u32 I) { bool Halted = false; bool Aborted = false; while (!Halted && !Aborted) { Halted = DebugStep(H_Hat, H_Hat); // Aborted = Needs_To_Be_Aborted(); } return Aborted; } void H_Hat(u32 P) // (bottom of page 319) { if (Aborted_Because_Non_Halting_Behavior_Detected(P, P)) HALT else HERE: goto HERE; } int main() { H_Hat(H_Hat); calls bool Aborted_Because_Non_Halting_Behavior_Detected(H_Hat, H_Hat) In the above case H_Hat(H_Hat) never terminates. -- Copyright 2020 Pete Olcott "Great spirits have always encountered violent opposition from mediocre minds." Einstein |
Tim Rentsch <tr.17687@z991.linuxsc.com>: Nov 08 11:03PM -0800 >> could be rearranged as suggested above is therefore not feasible. > To be clear, this rule isn't (quite) stated explicitly, but it > follows from the common initial sequence rule in N1570 6.5.2.3. Right. There is no explicit rule, it is only a consequence of other stated requirements. > In principle I suppose a compiler could violate the rule in cases > where it knows that there's no union containing a given structure > as a member, I think so, but it isn't easy to decide which sets of circumstances would allow it. There may not be a union in this TU, but I think there are cases where there is one in another TU that would prevent an alternate choice from being conforming. It's a messy problem. > but I can't think of any good reason to do so. Me either. In practical terms I believe there is no viable alternative. |
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