为什么 C++ 标准不更改 std::set 以使用 std::less<> 作为其默认模板参数?

xml*_*lmx 4 c++ standards backwards-compatibility c++14 c++20

#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
}
Run Code Online (Sandbox Code Playgroud)

v1.contains("abc"sv);比 更高效v1.contains("abc"s);,因为它不需要构造字符串对象。

但是,C++ 标准使用std::less<T>,而不是std::less<>,作为std::set默认模板参数。所以,CTAD(类模板参数推导)在 上不起作用std::less<>,我必须写得丑陋std::set<std::string, std::less<>>{"abc"s},而不是std::set{"abc"s}.

为什么 C++ 标准不更改std::set为用作std::less<>其默认模板参数?只是为了向后兼容?

Ded*_*tor 5

如果搜索关键字永远不需要转换,则从 转移到 可以使关键字查找算法更加高效std::set<T, std::less<T>>std::set<T, std::less<>>

相反,如果转换发生在每次调用比较器时,而不是在启动算法时在调用者中发生一次,则可能会降低它们的效率。这些转换可能非常昂贵。

特别是如果从搜索键到搜索键的转换T是有损的,甚至不能保证两者会产生相同的结果!

由于这些原因,这样的更改不是直接升级,而是破坏性更改。委员会非常不愿意介绍这些。