c++ - How does std::greater<> wоrk in a set?
问题描述
I know how std::greater works. But when I read the API of std::greater since C++14 it has a default type of void. So, if we don't pass any template argument to greater it defaults to void as below. But the result is as expected in descending order.
#include <iostream>
#include <set>
template< class T = void >
struct greater;
int main()
{
std::set<int, std::greater<>> s {4, 5, 6, 7}; // This transforms to std::set<int, std::greater<void>>
}
Can someone explain how this specialization works?
解决方案
It works by having the call operator be a function template instead of a function. Compare the old version to the new specialisation:
// greater<T>
bool operator()( const T& lhs, const T& rhs ) const;
// greater<void> i.e. greater<>
template< class T, class U>
auto operator()( T&& lhs, U&& rhs ) const;
What makes this great is the ability to compare objects of differing types.
This is crucial for example in case where given a string view, you need to look up whether an equivalent std::string
is stored in a set. Being able to compare string view to a std::string
allows us to not create a string from that string view. Which is good because std::string
can potentially be expensive to create.
With the old comparator, it could only compare std::string
to another std::string
in which case we would have to create a std::string
in order to look it up from a set of std::string
.
推荐阅读
- python - 无法打开本地文件路径的 URL
- javascript - 如何在没有ajax的情况下将变量从javascript传递给python?
- javascript - 测试组件DidUpdate酶reactjs
- .net - 无法访问作为 Windows 服务的 WCF 肥皂网络服务
- python - 如何在python中获取替换度数符号
- asp.net-mvc - 如何在 Asp.net MVC 中从 Azure 访问应用程序设置
- java - 在 JTextArea JAVA SWING 中突出显示下一个/上一个匹配项的 JButton
- azure-iot-hub - Azure IoT Edge Hub Python SDK 不能容错?
- javascript - 响应式导航栏在电脑上工作但在手机上不工作
- postgresql - 使用 Postgresql 移动/传输文件