#include <set>
#include <string>
#include <string_view>
using namespace std::literals;
int main()
{
auto v1 = std::set<std::string, std::less<>>{"abc"s};
v1.contains("abc"s); // ok
v1.contains("abc"sv); // ok
auto v2 = std::set{"abc"s};
v2.contains("abc"s); // ok
v2.contains("abc"sv); // error
}
v1.contains("abc"sv); is more efficient than v1.contains("abc"s);, because it needn't to construct a string object.
However, the C++ standard uses std::less<T>, rather than std::less<>, as std::set's default template argument. So, CTAD (Class Template Argument Deduction) doesn't work on std::less<>, I have to write ugly std::set<std::string, std::less<>>{"abc"s}, rather than std::set{"abc"s}.
Why does the C++ standard not change std::set to use std::less<> as its default template argument? Just for backward compatibility?
Moving from std::set<T, std::less<T>> to std::set<T, std::less<>> can make key-finding algorithms more efficient, if the search-key never has to be converted.
Conversely, it can make them less efficient if the conversion occurrs on every call to the comparator, instead of once in the caller on starting the algorithm. Those conversions can be quite expensive.
Especially if the conversion from search-key to T is lossy, there isn't even a guarantee both would yield the same result!
For these reasons, such a change is not a straight upgrade, but a breaking change. And the committee is quite loath to introduce those.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With