Further to the general theme of the thread - C++ compile times are bad, Go compile times are quite nice - I think this is significant when prototyping and testing units of code.
Also, getting all those libraries to compile with a particular compiler/stdlib combination is a big hassle. Things break in non obvious ways because of weird implicit template instantiations that are basically untestable by the creator of the library.
These types of integration issues are never going to go away and therefore C++ will occupy a stable niche forever but will never become mainstream for application development again, regardless of any language improvements.
C++ is used for a long list of specialized tasks like embedded systems, games, in-memory computing, database systems, high performance scientific stuff, some low latency trading algos and a few core UI things like browsers. I don't consider any of those mainstream application development.
If you don't want to decide then write all your types with value semantics and pass by value. How types are going to behave when passed should be decided before you write 'class{}'. It's a semantic decision. For types that you're borrowing, and not writing yourself, pass a shared_ptr or refer to the documentation.
-- Why should I be forced to decide how variables should be captured by a lexical closure?
Same thing applies. Auto capture[=] everything by value. If you're type doesn't have any (sane) value semantics, use a shared_ptr or a reference.
-- You can throw exceptions, except for the places where you cannot, and once caught you there is not much you can do to fix the problem.
You can throw an exception anywhere safely in correct code. The default assumption in the language is "anything can throw, any time, anywhere", so if your code doesn't at least provide the basic or weak exception guarantee you're swimming against the tide. Doing so usually improves the encapsulation and structure of code imo anyway.
-- once caught you there is not much you can do to fix the problem.
Exceptions are more like hardware exceptions or page faults than typical error states. You should only throw when you cannot reach a state expected by the caller. Ultimately, it comes down to API design, not philosophy.
... the better your API the better you can avoid having to throw. This isn't a new problem either, if you look at the C standard library there are many deprecated functions that provide no means of reporting an error at all except to return undefined results.-- extending the language is impractical.
Writing STL-like generic algorithms is trivial. Writing new data structures is trivial. Existing operators can be overloaded to augment scalar types or, more ambitiously, re-purposed to create DSLs. You have user-defined literals. Initializer lists and uniform intialization.
How would you like to extend further without it being completely alien to the existing language?
-- I actually switched away from C++ when I needed my code to scale better, because improving the scalability required a high-level approach and I did not have time to debug low-level problems
You should write more about this.
-- C++ gurus wind up having to deal with dangling pointers, buffer overflows, and other needless problems with their code
Not really bad pointers and buffer overflows these days. More slogging through pages and pages of compiler errors and hunting for library solutions to problems that should really be solved in the standard library (For me lately: ranges, matrices, more complex containers).
In any case, all languages have their share of friction. Look at that new Bitcoin daemon written in Go that hit the front page a few hours ago. The author had to debug 3 separate Go garbage collector issues.