You have to admit, it's hilarious that the most natural swap implementation you could possibly write (and the one used in C++03) is now "standout terrible." It's not wrong to point that out, but it is wrong to assign blame to the hapless programmer instead of the language.
And even if we make it not-generic, and add some C++11:
(It works if you use std::swap, I think because whatever type tmp resolves to happens to overload std::swap to do the right thing.)
So why is vector<bool> the "real problem?" It's because its operator[] doesn't return a bool&, but instead some type "convertible to bool," that may do lots of other stuff too. But the standard is chock-full of language like that. For example, with iterators: `str.begin() != str.end()` Is that a bool? `str.begin()[2]`. Is that a char? The standard doesn't require either. Care to roll the dice by assigning one to auto?
Type inference works well in other languages, but it is more dangerous in C++ due to the risk of implicit conversions. C++ does so much stuff for you under the hood that it can be quite hard to figure out what is really going on, and auto only makes that problem worse. Use with caution.
> You have to admit, it's hilarious that the most natural swap implementation you could possibly write (and the one used in C++03) is now "standout terrible." It's not wrong to point that out, but it is wrong to assign blame to the hapless programmer instead of the language.
The point wasn't that your swap implementation was bad, but that you would never write swap yourself. It was made even worse for generic code because types are expected to be able to provide their own swap implementation.
> So why is vector<bool> the "real problem?" It's because its operator[] doesn't return a bool&, but instead some type "convertible to bool," that may do lots of other stuff too. But the standard is chock-full of language like that. For example, with iterators: `str.begin() != str.end()` Is that a bool? `str.begin()[2]`. Is that a char? The standard doesn't require either. Care to roll the dice by assigning one to auto?
But the standard says that sequence containers with operator [] must return a reference, not a type convertible to T. If you wrote your swap implementation against the requirements of a container, it is fine, the problem is vector<bool> is not a container. As for other parts of the standard that do permit the type to only be [contextually] convertible to some type T, there is no rolling of the dice, your code is correct or it is not.
And even if we make it not-generic, and add some C++11:
We've fixed nothing. The problem remains!(It works if you use std::swap, I think because whatever type tmp resolves to happens to overload std::swap to do the right thing.)
So why is vector<bool> the "real problem?" It's because its operator[] doesn't return a bool&, but instead some type "convertible to bool," that may do lots of other stuff too. But the standard is chock-full of language like that. For example, with iterators: `str.begin() != str.end()` Is that a bool? `str.begin()[2]`. Is that a char? The standard doesn't require either. Care to roll the dice by assigning one to auto?
Type inference works well in other languages, but it is more dangerous in C++ due to the risk of implicit conversions. C++ does so much stuff for you under the hood that it can be quite hard to figure out what is really going on, and auto only makes that problem worse. Use with caution.