C++函子的类模板专用化
C++ class template specialization for functors
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;
它是一个 C++14 标准库功能,称为透明比较器。
以下声明都可以编译
std::set<int, std::greater<int>> s1; std::set<int, std::greater<>> s2;
第二种变体允许异构比较。在int
的情况下没什么大不了的,但考虑一下 N3657 中的示例:
std::set<std::string> s = /* ... */;
s.find("key");
在旧的 C++11 中,这将构造一个临时string
,以便 调用less(string, string)
。
在C++14中使用透明比较器,将自动生成less::operator() (const string&, const char*)
1,这将调用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
时,它默认为void
,在 C++14 中具有接受异构参数的专用化。这里的假设是没有人会在旧代码中使用std::greater<void>
,因此现有代码破译的风险很小。
有关更多详细信息,请参阅介绍"钻石运营商"的提案 N3421 和介绍std::is_transparent
的 N3657 。
1免责声明:确切的推导类型可能不同,这只是为了说明核心概念,而不涉及太多细节。
它是 C++14 功能吗?
是的,它是:
template< class T >
struct greater; // Until C++14
template< class T = void >
struct greater; // Since C++14
如果未指定类型T
,它将获得默认值void
。
规则是否在标准的某个地方定义?
从比较中:
template<class T = void> struct greater {
constexpr bool operator()(const T& x, const T& y) const;
};
相关文章:
- .cpp和.h文件中的模板专用化声明
- 调用专用模板时出错"no matching function for call to [...]"
- 模板专用化(按容器):value_type
- 静态数据成员模板专用化的实例化点在哪里
- 特征 3 类的模板专用化
- Visual Studio 2017 不允许我创建 C++ 专用模板
- 字符串化递归的"std::vector<std::vector<...>>"而不使用部分模板函数专用化
- 具有常量引用参数的函数模板专用化
- 使用其他模板的模板专用化
- 使用专用显卡进行 OpenGL 渲染时帧速率较低
- 嵌套模板显式专用化
- 如何检查模板专用化是否是基本模板的子类?
- C++:部分模板专用化用例
- 通过依赖类型使用非类型模板参数的单类型模板参数类模板的部分专用化
- 使用对象的基类部分模板专用化对对象进行哈希处理::哈希
- 在 C++20 中是否不再允许在 std 中对程序定义类型的函数模板进行专用化?
- 为什么依赖模板类型在部分专用化中不可推导?
- 如何为静态常量模板化专用整数值分配存储
- 模板类的部分模板专用化,如 std::function
- 合并一组模板专用化