On Sat, May 3, 2014 at 5:59 AM, Paul Colomiets <paul@xxxxxxxxxxxxxx> wrote: > Hi Peter, > >> I wonder if someone has tried to _implement_ nanomsg with C++11. > > You should probably read: > http://250bpm.com/blog:4 > http://250bpm.com/blog:8 These are common excuses why folks flat out reject C++; much less reconsider their position when adopting language advances in C++11 such as functional programming, lambdas, initializer lists, and so on. The fact is, when you do ABC expect ABC-issues to creep in; doesn't matter if you mode of delivery is C, C++, Python, Java, or C#. Personally, I'd rather know something was wrong with an exception than allow a corruption to slowly creep in with a failed C memory reference, type thing. Re: a couple of points in the blog: * handle_error() vs. throw std::exception() (or throw std::string(), or throw (int)1, for that matter). First off, in C++, yeah I know; C++ allows you to throw anything. Other languages are more precise. However, there's nothing stopping anyone from using "pure" C-isms in C++ code. You have to be aware of your compiler; however, C builds just fine in most C++ compilers. * ctor initialization. Take advantage of member initializers. Do be aware that virtualized methods do not work "as expected" in base classes, if class initialization is what you're aiming for. If necessary you can identify local method(s) to help with that; it's a matter of style and personal preference. * dtors vs. "terminated state". Again, matter of personal preference. I'll use the .NET IDisposable as an example. dtor or IDisposable instances are useful in a scope; typically in a using clause: Dispose is called automatically, so their lifetime is limited. On the other hand, you may have a pool of connection instances whose lifetime is persistent for the session; one "state" is connected, disconnected, etc. This is a completely separate concern from the lifetime of the instance. * pointer management. In a confined scope, it is usually unnecessary. Additionally, use references whenever possible; const or otherwise. It's like passing pointers but without the nasty dereferencing. * When it is necessary, I strongly consider smart pointers; at least unique pointer, possible shared pointer when appropriate. The referencing counting and this kind of thing is going to happen in some manner if I roll my own memory management utils anyway; why not let the implementation handle it for me (do be aware of implementations). Or a third party lib that I trust if I do not have confidence in the implementation; or roll my own smart pointers if I absolutely want to. As the author stated, there's no silver bullet; in my own words, there's no magic pill that will cure your ills. Adopt ABC, expect ABC-isms. For personal style, I am an object bigot, but not so much that I am unwilling to consider every option available to me. I have also grown to appreciate SOLID principles; especially when it comes to composing apps, decoupling concerns, injecting handlers in a functional way when I need to. I find that the solutions are better organized, the necessary abstractions scale and perform quite admirably, and are more maintainable (not perfect, just more; a software developer's shangri-la, so to speak). > -- > Paul >