The problem very often is that when you use qsort you call a precompiled library, only one copy of it exists, but when you use std::sort you may end up with many copies of the sort algorithm in memory. Not only is this a a lot of extra memory it also hurts run time because more memory means less locality of reference for caches and more likelihood of having to swap.
How should I address such a huge amount of bullshit? Let me start:
First, qsort only works on array types whereas std::sort works on anything that resembles a random input/output iterator;
Second, in the best case scenario, qsort has to resolve a function pointer and call a function for every comparison whereas std::sort needs neither, which is a monstrous performance loss for qsort;
Third, in the worst case scenario, qsort still has to resolve a function for every comparison whereas qsort doesn't, which is a huge performance loss for qsort;
Fourth, for all cases covered by qsort where the comparison is simply a return b > a;, only a single instance of std::sort is needed since only pointers are involved;
Fifth, if multiple instances of the template bother you more than the performance loss that you'd have with qsort, then providing std::sort with function pointers (as opposed to actual functions or functors) will ensure that only only one instance of the template is generated.
So, as you can see, std::sort is as bad as qsort in the worst case scenario (if you try really hard) and beats qsort to the ground in every other scenario.
In this case C++ hides too much of the details; if you want to write efficient code then you do not want details to be hidden. When you just want a rapid prototype then you don't need to worry about details. C++ can work well with both styles, however when you want efficiency you usually have to give up the ease of programming that high level generics and generic algorithms gives you.
Complete nonsense! Efficiency can be determined by the complexity of the underlying algorithm, which is usually known. For example, you know for a fact that accessing an std::map is O(log n) and that accessing an std::unordered_map is as close as possible to O(1). For further explanations as to why this paragraph is utter nonsense and you should feel incompetent at this point, read what I said about qsort vs std::sort above.
You CAN have type safe code with qsort. Either put a function wrapper around all uses of qsort that verifies all parameters are of the right type, or automatic this with a template wrapper around it. Then the sort routine itself remains efficient and precompiled in a library while still giving you the type safety that you want. It's only slightly more work than just using std::sort.
Your ignorance drives you to ridiculousness.
And using qsort as a "classic example" seems fishy. This is not a common source of errors and of all the places where type checking can mess up in C this is probably the least of the worries.
What qsort is an example of is a case where C code is A LOT SLOWER than C++ code, and there is no real workaround for this that doesn't involve losing even more functionality (you'd have to implement a non-generic solution in order to match the performance of the C++ generic implementation). Writing wrappers doesn't really solve anything, it only adds bloat to your code, which should be a concern to you were so worried about std::sort's multiple instances, and you aren't allowed to talk about templates because those don't exist in C.
TLDR: If you are a software engineer, you are an incompetent buffoon.