Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the C++ standard not change std::set to use std::less<> as its default template argument?

#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?

like image 798
xmllmx Avatar asked Nov 06 '25 17:11

xmllmx


1 Answers

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.

like image 181
Deduplicator Avatar answered Nov 09 '25 07:11

Deduplicator