- Dependecy Injection - 3 Updates
- Idiots (reprise) - 2 Updates
- Core language basic types support - 11 Updates
- C++ Exception Handling - 1 Update
- OS X, iOS and Linux have more vulnerabilities than Windows - 1 Update
- Visual C++ (2015 Update 1) bug, oder? - 2 Updates
- cmsg cancel <n4ak17$b7m$6@dont-email.me> - 1 Update
- Does the function below show undefined behavior? - 1 Update
- Space efficiency when using vectors. - 2 Updates
- Object initialization confusion - 1 Update
"Tobias Müller" <troplin@bluewin.ch>: Dec 12 07:55AM >> I see no big difference except the increased verbosity of templates. > Resulting in the template keyword spreading like a virus in your code > with a proportional increase in compilation time and binary file size. If you want static polymorphism everywhere then yes, that's the price to pay. Compilation will increase for sure, binary size depends. In practice you probably won't have too many different instantiations and with better optimization possibilities size could probably even decrease. > The big difference is having dependencies on abstractions rather than > concretions results in looser coupling and better design sausages. Nothing prevents you from still having an IBar interface. Bar beeing a template itself is orthogonal to that. I'm not saying that runtime polymorphism is generally bad and templates should always be preferred. But if you need the performance it's a valid alternative for achieving DI. Tobi |
Christopher Pisz <nospam@notanaddress.com>: Dec 10 06:33PM -0600 The concept of dependency injection is becoming a thing where I work for all the .NET guys. I barely understand it having never been exposed in my C++ bubble of 1 programmer on the team for some time. If I understand the programming pattern itself, it simply means to pass dependencies at construction time as interfaces to a class. This way, the class isn't aware of what concrete implementation it is using. Seems like I've been doing that all along anyway...Is there more to it? At least in .NET land, there seems to be some hinting at "configuring which concrete implementation to use" that goes along with this. I guess they do it in one of the many configuration files visual studio generates with a project through some magic library, but I don't know. Do we have something similar we can do in C++? It seems like it would be very useful to configure a particular implementation to use without having to recompile, especially for unit tests when there is a desire to use a mock/proxy interface. Are there any good articles to read or examples to go over that I should be aware of? Is this a thing for us too? -- 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 --- |
Victor Bazarov <v.bazarov@comcast.invalid>: Dec 10 09:41PM -0500 On 12/10/2015 7:33 PM, Christopher Pisz wrote: > tests when there is a desire to use a mock/proxy interface. > Are there any good articles to read or examples to go over that I should > be aware of? Is this a thing for us too? Sounds like a marriage between a pimpl idiom and a factory pattern. V -- I do not respond to top-posted replies, please don't ask |
Ian Collins <ian-news@hotmail.com>: Dec 11 11:00AM +1300 Mr Flibble wrote: > Some of the idiotic things that regulars of this newsgroup still > continue to advocate: Most of what followed was debunked last time you posted it. Have you run out of sausages? -- Ian Collins |
Ian Collins <ian-news@hotmail.com>: Dec 11 11:10AM +1300 Gareth Owen wrote: >> Most of what followed was debunked last time you posted it. Have you >> run out of sausages? > Please do not treat the issue of running out of sausages with levity. Oh I don't. I maintain multiple redundant sources to mitigate that risk. -- Ian Collins |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Dec 11 05:59AM +0100 On 12/11/2015 5:24 AM, Nobody wrote: > What does this actually mean? Or rather, why doesn't wchar_t count? > Admittedly, wchar_t isn't guaranteed to be Unicode. But if it isn't, > that's usually because the platform itself doesn't support Unicode. In practice wchar_t is guaranteed to be Unicode (I don't know of any exception), but Unix-land OS APIs don't take wide string arguments. E.g., the Unix-land "open" function takes a narrow string, // http://pubs.opengroup.org/onlinepubs/009695399/functions/open.html int open(const char *path, int oflag, ... ) The corresponding function in Windows is the appropriate mode of the all-purpose CreateFileW function, which takes wide strings or (via a wrapper called CreateFileA) Windows ANSI-encoded narrow strings. This matters both for the case where such functions are used directly (C++ is not only for writing portable code), and for the case where one desires to write a portable interface with system-dependent implementation that should not need to convert encodings and do dynamic allocation and such... An example of such an interface is the Boost filesystem library, which will be part of C++17. It kludge-solves the issue by requiring wide string based stream constructors in Windows, but I think that singling out a specific OS in the specification of a standard library component for C++, is a very very bad approach, and so needless – it would not be a problem with core support for a syschar. Cheers & hth., - Alf |
David Brown <david.brown@hesbynett.no>: Dec 11 10:44AM +0100 On 10/12/15 17:41, Alf P. Steinbach wrote: > unsigned type, as very unnecessary: just by using signed types for > numbers, and reserving unsigned types for bitlevel stuff, it's avoided. > Well, mostly. ;-) OK. I know that mixing signed and unsigned can introduce subtle errors, so I can understand if you want to avoid it. (My own use is a little different, and I use unsigned types a lot - but then, I do low-level programming on small embedded systems, and therefore much more "bitlevel stuff".) > In the single case (that I know of) where the C++ standard library > represents a size as signed, namely "count" and "count_if", it uses the > iterator difference type, which for pointers is "ptrdiff_t". I would then say that C++ itself does not need a standard signed size type - if you are using Posix, then you've got "ssize_t", and if you are using "count" you have ptrdiff_t. But if you want a nicely named signed size type for your own use, that seems fair enough. > C++ now supports Posix, at least to some degree. In particular with > C++11 conversions between function and data pointers, required by Posix, > was allowed. It's up the implemention whether it's allowed. Posix is not supposed to work on /all/ C++ implementations. It makes certain requirements of the C or C++ implementation beyond the standards. For example, it requires two's complement signed integers, 8-bit chars, and 32-bit int. So Posix has always relied on certain implementation-dependent features of C and C++ - but they are ones that are valid on all systems for which Posix is realistic. >> dependent, in that they may not actually be 8-bit, 16-bit or 32-bit on >> all systems, but otherwise they are standardised. > No, that's not usefully system dependent. I don't see system dependent as a good thing here - in fact, I see it as a bad thing. > That's the kind of portability that "int" offers: it's right for the > system at hand, and yields one common source code that adapts > automatically to the system it's compiled on. I am actually much happier that you /don't/ have that. You can write u8"Blah" and have the string as a utf8 string, or U"Blah" for a utf32 string. Plain old strings give you the default system-dependent 8-bit character encoding, which is suitable for plain ASCII and little else. If you want to write code that is tied directly to a particular OS and its API, you can use the types that suit that OS - utf8 for *nix, utf16 for Windows (and hope that you don't fall foul of the UCS16/utf16 mess). The types there are clear. If you want to write code that is independent of the OS, you use a cross-platform library in between so that your code can stick to a single format (usually utf8 or utf32) and the library handles the OS-specific part. > Yes, but it's in the wrong direction. > I was talking about casting (back) to signed, without giving the > compiler Unsound Optimization Ideas™ based on formal UB here and there. Sorry, I misread you here. Converting from signed to unsigned is well-defined, while converting from unsigned to signed has implementation-defined behaviour when the value cannot be represented. It is not undefined behaviour, so there is no "compiler problem". I don't know for sure about other compilers, but gcc (and therefore llvm, which follows gcc in these matters) implements modulo behaviour here. Since all signed integers in gcc are two's complement, that means the compiler will simply re-interpret the same bit pattern as a signed value. It would surprise me if the implementation-defined behaviour was any different on other compilers, at least for "nice" target architectures. > unsigned, exactly as you showed here, as a first step, to get > well-defined modulo wrapping). I guess it can be done in a more elegant > way. And not sure if it /really/ avoids the compiler problem. There is no compiler problem here as far as I can see (see above). The only issue could be implementation-defined (but not undefined) behaviour being different on some compilers. >> Would it make sense to put "constexpr" in the code in some cases? > Not sure. Do you have something in particular in mind? I'm still at the > stage where I only add "constexpr" where it's directly needed. I was thinking for cases like "is_ascii" (though you need C++14 for the loop - in C++11 you'd need to use recursion), and wrap_to. Basically, using "constexpr" restricts what you can do in the function (less so in C++14), but means that the compiler can pre-calculate it (if the parameters are constant) and use the results in more contexts. So when the restrictions on the features needed in the function are not a limitation, it adds flexibility that could be useful in this sort of code. |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Dec 11 01:32PM +0100 On 12/11/2015 10:44 AM, David Brown wrote: > cross-platform library in between so that your code can stick to a > single format (usually utf8 or utf32) and the library handles the > OS-specific part. Consider if that was so for integers, that one needed some 3rd party library to interface the integers with the OS API, converting back and forth. It's possible but it's just needlessly complex and inefficient. > Sorry, I misread you here. Converting from signed to unsigned is > well-defined, while converting from unsigned to signed has > implementation-defined behaviour when the value cannot be represented. Hm, you're right. All that the function does technically then is to avoid a sillywarning with Visual C++ 2015 update 1, but that sillywarning can instead be turned off. Grumble grumble... > It is not undefined behaviour, so there is no "compiler problem". Well, not so fast. But right, the conversion is implementation defined behavior. Thanks, it slipped my mind! > parameters are constant) and use the results in more contexts. So when > the restrictions on the features needed in the function are not a > limitation, it adds flexibility that could be useful in this sort of code. C++14 sounds good, after all we're in 2015. But I'll have to experiment to find out what Visual C++ 2015 supports. E.g. it doesn't yet (as of update 1) support variable templates. Cheers, & thanks, - Alf |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Dec 11 02:57PM +0100 On 12/11/2015 1:32 PM, Alf P. Steinbach wrote: > C++14 sounds good, after all we're in 2015. But I'll have to experiment > to find out what Visual C++ 2015 supports. E.g. it doesn't yet (as of > update 1) support variable templates. Unfortunately the following code does not compile with MSVC 2015 update 1 (the latest version of Visual C++) when NEWFANGLED is defined, although it does compile with MinGW g++ 5.1.0: <code> #ifdef NEWFANGLED template< class... Args > constexpr auto exactly_one_of( const Args&... args ) -> bool { const bool values[] = {!!args...}; int sum = 0; for( bool const b : values ) { sum += b; } return (sum == 1); } #else inline constexpr auto n_truths() -> int { return 0; } template< class... Args > constexpr auto n_truths( const bool first, Args const&... rest ) -> int { return first + n_truths( rest... ); } template< class... Args > constexpr auto exactly_one_of( const Args&... args ) -> bool { return (n_truths( !!args... ) == 1); }
Subscribe to:
Post Comments (Atom)
|
No comments:
Post a Comment