First, I agree with Eric about not adding yet another dimension of configuration to libc++. I know for you it might appear like just a convenience, however the number of configurations supported by libc++ is already too large to maintain, so the only thing we should do is reduce it, not increase it.
OK, let’s unconditionally re-enable these types/functions, and provide no mechanism to disable them. That reduces the configuration dimensions compared to now. We emit deprecation warnings, in any case.
On a different level, I believe that libc++ should implement the Standard, and the Standard has decided to remove these features from C++17. Hence, I believe it is entirely reasonable for libc++ not to provide these features in C++17, and in fact I view the fact that we allow un-removing them merely as a gentle approach to help people upgrade. In the future, I believe that we should unconditionally remove these features from C++17.
I think it’s a great idea to update the standard mode for Clang to C++17 (or Gnu++17), however I don’t think libc++ should bend itself in order to make arbitrary code bases compile out-of-the-box when they don’t conform to the Standard mode they are trying to use. It seems to me like either:
(1) these code bases are not maintained anymore and there’s no intent to update them, so it’s better for them to just acknowledge that and compile them as C++14, or
(2) these code bases are maintained, and we’re trying to use these removed features to save the work of actually updating the code base.
In both cases, I think that providing these removed features in C++17 is just playing ostrich with the real issue.
Yet very unfortunately, C++ does not make it possible to just compile “old” code in C++14 and the “new” code in C++17. A single dependency which continues mentioning std::bind1st in its header can prevent you from using c++17 for all of your code that depends on it. And with much of C++ living in headers, and with there being no way to declare a standards-version just for one section of code (or, dare I say, “module”), this is problematic. Furthermore, even if the std::bind1st call is in an implementation file, selecting a different standards mode when building only that translation unit carries the risk of ODR issues from entities defined in other headers it includes. You can often get away with this anyways, but it’s better not to…
So, “just fix all the code”? Yes, of course that’s possible, but that’s painful. Maybe very painful, depending on how much of other people’s code you’re depending on.
Given the downsides, what’s the counterbalancing benefit to removing these symbols? There seems to be no maintenance benefit to libc++ itself, because the implementation must remain. It’s not a standards-compliance issue, because the Standard explicitly blesses implementations continuing to provide these removed features, despite having removed them.
I think the argument is that breaking our users’ code is for their own benefit – this way they are made aware that they’re using a feature which was determined to be bad, and are thus forced to stop doing so. I don’t find this a convincing argument – the benefit here this seems very much outweighed by the downsides – but I don’t know how to actually quantify that.