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