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.
// Clearly the only sane thing to do here if you
can't stat() the file is throw an exception.
size_t get_file_size(string filename);
// Some flexibility. Could probably avoid throwing.
optional<size_t> get_file_size(string filename);
// Better still, and easy to overload with the above
optional<size_t> get_file_size(string filename, error_code&);
... 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.