Personal opinions on the "right subset" of C++:

* Yes to classes.

* Yes to inheritance and virtual member functions, because interfaces are a very useful and easy to understand abstraction. Moreover, especially for games, idioms such as "class Monster : public DamageableObject" are really the most natural thing. However, avoid situations in which you need dynamic_cast like the plague. No to virtual inheritance.

- I really wish class memory layout were standardised more, but at least some non-standard assumptions are fairly safe in my experience: e.g. class A : B {...} ... B * x; assert((long)static_cast<A* >(x) == (long)x);

* Before you start using "friend class", consider whether you could get around it somehow. If a class is not public-facing, set everything public and enforce encapsulation by self-discipline rather than language features.

* Yes to templates in their C++ 101 application of making a $type-specialised version of classes and functions. No to using them to perform any real compile-time computation, or anything of the type Boost pulls. No to Boost.

* "Keep the parts of your code that only do C stuff in C".

- printf over iostream.

- (de)allocate classes with new/delete, but POD with malloc/free

- exception: std::string over char* , because it is really that much more convenient

* Yes to lambdas, but only pass them as function arguments if there is no good alternative, because of legibility. Avoid stuff like the for_each(..., []{ ... }) in the Ranges example.

* Yes to STL containers and algorithms, because everyone knows how they work and they are usually good enough.

* Range-based for over for(std::container::iterator i=...). Using the Ranges TS when a plain for loop would do strikes me as novelty-chasing and violates "do C stuff in C".

* Cautious yes to auto. It does somewhat detract from comprehension in some use cases. Don't just auto everything because you are too lazy to figure out the type.

* std::shared_ptr only when you actually think you can't answer the question of what the appropriate point to deallocate a piece of memory is, or at least not without significantly changing the structure of your code.

* Avoid std::tuple, std::variant and other awkward STL attempts to replicate functional language idiom without the syntactic support. It's terrible to read. Unfortunately, STL containers sometimes force you to use pair.

* No to exceptions; their interaction with other language features is awkward, and the eternal difficulties with platform support make me feel no confidence in the reliability of the feature. (I'm unfamiliar with the bowels of the implementation, but it seems like unwinding C++ stacks is fundamentally a hard problem.)

* No to novelty features such as user-defined literals.

* goto only to break out of multiple levels of nested loops.

* Coroutines strike me as something that's unambiguously cool but so far removed from the standard idiom of C++ programming that I'm inclined to say no. Maybe there's an alternative style guide you could write that says yes to coroutines and no to some of the things above. Multi-paradigm should not mean "use all the paradigms".

(I'm very happy to be persuaded otherwise on any of these points.)