std::set
具有以下模板参数:
template<typename _Key, typename _Compare = std::less<_Key>,
typename _Alloc = std::allocator<_Key> >
class set
std::greater
具有以下模板参数:
template<typename _Tp>
struct greater : public binary_function<_Tp, _Tp, bool>
以下声明都可以在gcc 7.1上编译。我不明白为什么第二个声明是有效的。它是C ++ 14的功能吗?规则是否在标准的某处定义?
std::set<int, std::greater<int>> s1;
std::set<int, std::greater<>> s2;
答案 0 :(得分:3)
它是C ++ 14的功能吗?
template< class T >
struct greater; // Until C++14
template< class T = void >
struct greater; // Since C++14
如果未指定类型T
,则会获得默认值void
。
答案 1 :(得分:3)
这是一个名为transparent comparators的C ++ 14标准库功能。
以下声明都可以编译
d | to_char ------------------------+--------- 2018-02-09 08:17:17+00 | 2018_02 2018-03-09 08:17:17+00 | 2018_03 (2 rows)
第二种变体允许进行异构比较。在std::set<int, std::greater<int>> s1;
std::set<int, std::greater<>> s2;
的情况下没什么大不了的,但请考虑N3657的例子:
int
在旧的C ++ 11中,这将构造一个std::set<std::string> s = /* ... */;
s.find("key");
临时代码
调用string
。
使用C ++ 14中的透明比较器,将自动生成less(string, string)
1 ,这将调用less::operator() (const string&, const char*)
,从而避免临时。
它的实施方式是:
bool operator< (const string&, const char*)
也就是说,当没有指定template< class T = void >
struct greater;
template <> struct greater<void> {
template <class T, class U> auto operator()(T&& t, U&& u) const
-> decltype(std::forward<T>(t) > std::forward<U>(u));
};
时,它默认为T
,它在C ++ 14中具有接受异构参数的特化。这里的假设是没有人会在旧代码中使用void
,因此现有代码破解的风险很小。
有关详细信息,请参阅提案N3421,其中介绍了&#34;钻石运营商&#34;和N3657,其中介绍了std::greater<void>
。
1 免责声明:确切的推断类型可能有所不同,这只是为了说明核心概念而不会过多详细说明。
答案 2 :(得分:1)
规则是否在标准的某处定义了?
template<class T = void> struct greater {
constexpr bool operator()(const T& x, const T& y) const;
};