C++ 什么是透明比较器?
在C++14中,关联容器似乎与C++11有所不同–[associative.reqmts]/13表示: 成员函数模板C++ 什么是透明比较器?,c++,c++14,c++-faq,C++,C++14,C++ Faq,在C++14中,关联容器似乎与C++11有所不同–[associative.reqmts]/13表示: 成员函数模板查找、计数、下限、上限和相等范围不得参与重载解析,除非类型比较::是透明的 使比较国“透明”的目的是什么 C++14还提供如下库模板: template <class T = void> struct less { constexpr bool operator()(const T& x, const T& y) const; typed
查找
、计数
、下限
、上限
和相等范围
不得参与重载解析,除非类型比较::是透明的
使比较国“透明”的目的是什么
C++14还提供如下库模板:
template <class T = void> struct less {
constexpr bool operator()(const T& x, const T& y) const;
typedef T first_argument_type;
typedef T second_argument_type;
typedef bool result_type;
};
template <> struct less<void> {
template <class T, class U> auto operator()(T&& t, U&& u) const
-> decltype(std::forward<T>(t) < std::forward<U>(u));
typedef *unspecified* is_transparent;
};
无模板结构{
constexpr bool操作符()(const T&x,const T&y)const;
typedef T第一个参数类型;
typedef T第二个参数类型;
typedef bool result_type;
};
无模板结构{
模板自动运算符()(T&&T,U&&U)常量
->decltype(std::forward(t)
例如,std::set
将没有一个透明的比较器,但是std::set
将有一个
这解决了什么问题?这会改变标准容器的工作方式吗?例如,
std::set
的模板参数仍然是键,Compare=std::less,
,那么默认集是否会丢失其find
,count
,等等。成员?在C++11中,没有成员模板find()
,下限()
,等等。也就是说,此更改不会丢失任何内容。n3657引入了成员模板,以允许在关联容器中使用异构键。我没有看到任何具体的例子,这是有用的,除了例子是好的和坏的
是透明的
用途旨在避免不必要的转换。如果成员模板不受约束,现有代码可能会直接通过对象,而这些对象在没有成员模板的情况下会被转换。n3657中的示例用例是使用字符串文本在std::set
中定位对象:在C++11定义中,将字符串文本传递给相应的成员函数时,将构造std::string
对象。通过更改,可以直接使用字符串文字。如果底层比较函数对象是按照std::string
专门实现的,这是不好的,因为现在会为每个比较创建std::string
。另一方面,如果底层比较函数对象可以采用std::string
和字符串文本,则可以避免构造临时对象
比较函数对象中的嵌套是透明的
类型提供了一种指定是否应使用模板化成员函数的方法:如果比较函数对象可以处理异构参数,它将定义此类型以指示它可以有效地处理不同的参数。例如,新的操作符函数对象只是委托给operator,以下都是从中复制的
问:使比较国“透明”的目的是什么
A.关联容器查找函数(查找、下界、,
上限,相等范围)仅接受键类型的参数,需要
用户构造(隐式或显式)的对象
键入键以执行查找。这可能很昂贵,例如,建造一个
当比较器仅起作用时,要在集合中搜索的大型对象
查看对象的一个字段。用户有强烈的愿望
能够使用与
按键类型
这能解决什么问题
A.LWG对以下代码表示关注:
std::set<std::string> s = /* ... */;
s.find("key");
std::set s=/*…*/;
s、 查找(“密钥”);
在C++11中,这将构造一个std::string temporary,然后
将其与元素进行比较以找到键
通过N3465提出的更改,std::set::find()函数将
是一个不受约束的模板,可以通过
对于比较器函数,std::less
为每次比较构造一个std::string临时。LWG
认为此性能问题是一个严重的问题。这个
template find()函数还可以防止在
指针容器,导致以前有效的代码不再
编译,但这被视为一个比沉默更不严重的问题
性能回归
这是否改变了标准容器的工作方式
A.本提案修改了和中的关联容器
通过使用成员函数重载查找成员函数
模板。没有语言变化
那么默认集合是否会丢失其find、count等成员
几乎所有现有的C++11代码都不受影响,因为
除非使用新的C++14库功能,否则函数不存在
作为比较函数
引用
在C++14中,std::set::find是一个模板函数,如果
比较::是否透明存在。您传入的类型不需要
在你的比较仪下是关键的,只是同等的
和n3657
在23.2.4【关联需求】中增加第13段:
成员函数模板查找、下限、上限和
除非
类型比较::是否透明不存在?是否存在
提供了一个示例
这个
这解决了什么问题,
见和
这会改变标准容器的工作方式吗
不,不是默认的
新的成员函数模板重载find
等。允许您使用与容器的键类似的类型,而不是使用键类型本身。请参见Joaqín MªLópez Muñoz关于增加这一功能的理由和详细、仔细编写的建议
在布里斯托尔会议上,LWG同意
template<typename T, typename Cmp = std::less<>, typename Alloc = std::allocator<T>>
using set = std::set<T, Cmp, Alloc>;