Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 什么是透明比较器?_C++_C++14_C++ Faq - Fatal编程技术网

C++ 什么是透明比较器?

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中,关联容器似乎与C++11有所不同–[associative.reqmts]/13表示:

成员函数模板
查找
计数
下限
上限
相等范围
不得参与重载解析,除非类型
比较::是透明的

使比较国“透明”的目的是什么

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>;