- tuple (explicit?) constructors, overload resolution - 2 Updates
- To name, perchance pleasingly - 2 Updates
- About PhDs in computer science.. - 1 Update
- EXAMPLE - 1 Update
- Simple Proxy Collector... - 1 Update
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Mar 30 08:49AM +0200 On 29.03.2018 18:18, Latimerius wrote: > It's not compilable as the constructor call in main() is apparently ambiguous. Two things that I don't understand about this: > 1) why does the second C's ctor even apply? Shouldn't the corresponding std::tuple ctor be explicit? > 2) assuming both C's ctors are applicable - shouldn't the first one be a better match? I guess it only requires a single conversion (from lambda to C:::Fn) whereas the second one requires two (lambda to C::Fn as before and then from C::Fn to std::tuple). Both `tuple` and `function` have templated constructors that can take just about any argument. One way to disambiguate is to use a templated constructor that checks the kind of argument (e.g. via a traits class like below) and forwards to a constructor with explicit mention of the kind of argument: #include <functional> #include <tuple> #include <iostream> #include <type_traits> namespace arg { struct Some_type {}; struct Tuple {}; }; namespace c_arg { template< class Arg > struct Kind_ { using T = arg::Some_type; }; template< class F > struct Kind_<std::tuple<F>> { using T = arg::Tuple; }; template< class F > using Kind = typename Kind_<F>::T; } struct C { using Fn = std::function <void (int )>; Fn mFn; C( arg::Some_type, Fn fn ) : mFn{ std::move( fn ) } { mFn( 1 ); } C( arg::Tuple, std::tuple <Fn> t ) : mFn{ std::move( std::get<0>( t )) } { mFn( 2 ); } template< class Arg > C( Arg&& arg ) : C{ c_arg::Kind<std::remove_reference_t<Arg>>{}, std::forward<Arg>( arg ) } {} }; auto main() -> int { auto lambda = [](int i) { std::cout << i << std::endl; }; std::tuple<std::function<void(int)>> t{ lambda }; C c1{ lambda }; C c2( t ); } In practice this technique is used to disambiguate * rvalue reference versus reference to const, for templated type, * raw array versus pointer, for templated type. Cheers & hth., - Alf |
Latimerius <l4t1m3r1us@gmail.com>: Mar 30 01:32PM -0700 Thanks for the advice on how to disambiguate - this is going to be useful. Could you also help me understand why the constructor call is ambiguous in the first place? Apparently I need to fix my understanding of overload resolution. My current understanding leads me to believe that the tuple-taking constructor should require one more argument conversion and thus be a worse candidate. However, both g++ and clang++ disagree... |
Tim Rentsch <txr@alumni.caltech.edu>: Mar 29 11:49PM -0700 > I suppose cbor::value (msgpack::value) would be an option, but value by > itself seems uninspired. Or perhaps cbor::packed (msgpack::packed), as > these encapsulate packed arrays of bytes. I've kept all the context so as not to have to decide what to cut. I think 'cbor' is a good choice for the name of the namespace (in case it needs saying, given the context with parallel namespaces such as msgpack, etc). I think 'value' is a poor choice for a class name. It doesn't say anything, kind of like 'cbor::thing'. The name 'packed' is at least more descriptive than 'value', but still IMO a poor choice. If I were charged with proposing a name (and following the rule of no uppercase letters), I think my first suggestion would be 'encoded_item'. (Needless to say that assumes that an instance of the class does indeed hold an encoded item.) My rationale is this name leaves no doubt in the reader's mind what an instance of this class represents. It doesn't require any guessing, imagination, or outside context, to undrstand what is meant. Does that all make sense? |
Daniel <danielaparker@gmail.com>: Mar 30 10:40AM -0700 On Friday, March 30, 2018 at 2:50:07 AM UTC-4, Tim Rentsch wrote: > guessing, imagination, or outside context, to undrstand what > is meant. > Does that all make sense? Thanks for your comments and suggestions. I think all the comments agreed that the namespace name should be cbor (singular). For class name, 'encoded_item' could work, but I'm also inclined to a little repetition as suggested in Richard's post and include "cbor" in the class name. I agree with your comments about value as a class name. I tentatively went with boost's approach for tuple, iterator, and bimap (subdirectory singular, namespace plural, class name singular), hence cbor (subdirectory), cbors (namespace) and cbor (class name). But I'm not enthusiastic about it (partly from reflecting on comments on this thread) and am thinking of changing it to cbor, cbor, and packed_cbor. Daniel |
Tim Rentsch <txr@alumni.caltech.edu>: Mar 29 11:27PM -0700 > I know better than to engage with a known troll, but.... but... some days you just have poor impulse control? (just a friendly rib - I must plead guilty to the same offense :) |
Tim Rentsch <txr@alumni.caltech.edu>: Mar 29 11:23PM -0700 > So in the end, if everyone had been writing mostly ~50 line routines, > I don't think the lack of structure within those routines would have > attracted too much attention. I pretty much agree with all of the above. I might emphasize that it is the drive for understandable programs that leads to small routines, and not that a drive for small routines will necessarily lead to understandable programs. (And which I believe is one of the points you were making, or at least would agree with.) > arbitrary set of rules. I'm good with whatever makes a program > clearer. On occasion, that involves a goto. We know you *can* always > do without, but sometimes the cure is worse than the disease. Yes. Even Dijkstra said he wasn't dogmatic about avoiding goto. My point though is about size. Routines of 50 lines can be manageable, and certainly they are more likely to be manageable than routines of 100 or 200 lines. Still, 50 line routines should be rare rather than typical. Average function length normally should be under 20 lines, and median length closer to 10. A length of 50 lines should normally be 95th percentile or better - anything worse is a strong indication that some refactoring is needed. Like what you said, I don't mean to make an arbitrary rule, but to give a useful empirical guideline for after-the-fact assessment. >> and hope you will explain.) > My experience is that those usages are pretty much interchangeable in > the field. Although I'd agree that in linguistic terms they're not. I agree that misusage is common, but still deserves being called out. There are two problems. The first is that different people use the term in different ways - does it mean usual, widespread, normal, typical, common, well-understood, generally accepted, or some combination of those, or perhaps something else entirely? There are arguments over whether some construction is or is not "idiomatic". Or, another example, someone asking for "/the/ idiomatic way" (my emphasis) to write a particular program. There is never a single good way to write a program (and yes sometimes "idiomatic" is used as though it were synonymous with "good"). Being precise is an important habit in software development; continuing the definitely imprecise use of "idiomatic" is cultivating a bad habit. The second problem is more subtle. The word "idiomatic" sounds, by virtue of its length and narrow application, like a high-brow word. Characterizing a pattern as "idiomatic" lends an air of legitimacy that often is not deserved. At some level this kind of usage is intellectually dishonest (even if not always consciously or deliberately): it sounds objective, but as often as not boils down to nothing more than "a pattern I think is good". That kind of rhetorical trick is best left to the domain of politicians (where for better or worse it appears to be inescapable). |
"Chris M. Thomasson" <invalid_chris_thomasson@invalid.invalid>: Mar 29 09:30PM -0700 On 3/27/2018 8:55 PM, Chris M. Thomasson wrote: > function. > Here is my C++11 code [1]: > https://pastebin.com/raw/KAt4nhCj [...] > Thanks. > [1] code: > ___________________________ [...] > ___________________________ Perhaps I can explain this through a series of questions. Let me try to start... Question 1 How many people want to iterate over a shared data-structure without using a read/write mutex? In other words, would making the writers run concurrently with the readers be beneficial to you at all? Readers can run full steam ahead, while the writers do not interrupt them. This can, increase concurrency and overall performance, and can get rid of certain bottlenecks especially if the problem is mostly read based. |
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