什么是透明比较器? [英] What are transparent comparators?

查看:208
本文介绍了什么是透明比较器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C ++ 14中,关联容器似乎已经从C ++ 11改变了– [associative.reqmts] / 13说:

In C++14, associative containers seem to have changed from C++11 – [associative.reqmts]/13 says:


成员函数模板 find count lower_bound upper_bound 和<$ c $除非 Compare :: is_transparent 类型存在,c> equal_range 不得参与重载解析。

The member function templates find, count, lower_bound, upper_bound, and equal_range shall not participate in overload resolution unless the type Compare::is_transparent exists.

使比较器透明的目的是什么?

What is the purpose of making an comparator "transparent"?

C ++ 14还提供类似这样的库模板: / p>

C++14 also provides library templates like this:

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

例如, std :: set< T,std :: less< ; T>> 不是有透明比较器,但 std :: set< T,std :: less< / code> 有一个。

So for example, std::set<T, std::less<T>> would not have a transparent comparator, but std::set<T, std::less<>> would have one.

这解决了什么问题,例如, std :: set 的模板参数仍然为 Key,Compare = std :: less< Key> ;, ... ,那么默认集合会失去其 find count 等成员吗?

What problem does this solve, and does this change how standard containers work? For example, the template parameters of std::set are still Key, Compare = std::less<Key>, ..., so does the default set lose its find, count, etc. members?

推荐答案


这解决了什么问题,

What problem does this solve,

请参阅Dietmar和remyabel的回答。

See Dietmar and remyabel's answer.


这样会改变标准容器的运作方式吗?

and does this change how standard containers work?

否,不是默认值。

新的成员函数模板重载 find 等允许你使用一个类似于容器的键,而不是使用键类型本身。请参阅JoaquínMªLópezMuñoz的 N3465 了解理由和详细信息

The new member function template overloads of find etc. allow you to use a type that is comparable with the container's key, instead of using the key type itself. See N3465 by Joaquín Mª López Muñoz for rationale and a detailed, carefully written proposal to add this feature.

在布里斯托尔会议上,LWG同意这个独特的查找功能是有用和可取的,但我们不能确定Joaquín的提案在所有情况下都是安全的。 N3465提案会对某些程序造成严重问题(请参阅对现有代码的影响部分)。 Joaquín编写了一份更新的草案,其中有一些替代实现,具有不同的权衡,这对于帮助LWG理解其优缺点是非常有用的,但它们都有可能以某种方式破坏一些程序,因此没有达成一致意见。我们决定,虽然无条件地添加功能是不安全的,但如果默认情况下禁用并且只选择选择加入,则它是安全的。

At the Bristol meeting the LWG agreed that the heteregeneous lookup feature was useful and desirable, but we could not be sure that Joaquín's proposal would be safe in all cases. The N3465 proposal would have caused serious problems for some programs (see the Impact on existing code section). Joaquín prepared an updated draft proposal with some alternative implementations with different trade-offs, which was very useful helping the LWG understand the pros and cons, but they all risked breaking some programs in some way so there was no consensus to add the feature. We decided that although it wouldn't be safe to add the feature unconditionally, it would be safe if it was disabled by default and only "opt in".

N3657 提案的差异(这是最后一分钟根据 N3465 和以后未发布的内容,我自己和STL进行修订Joaquín的草案)添加 is_transparent 类型作为可用于选择启用新功能的协议。

The key difference of the N3657 proposal (which was a last-minute revision by myself and STL based on N3465 and a later unpublished draft by Joaquín) was to add the is_transparent type as the protocol that can be used to opt in to the new functionality.

如果你不使用透明函子(即定义一个 is_transparent 类型),那么容器的行为与他们总是做的一样,

If you don't use a "transparent functor" (i.e. one that defines a is_transparent type) then the containers behave the same as they've always done, and that's still the default.

如果您选择使用 std :: less<>

使用 std :: less<> 很容易与别名模板:

Using std::less<> is easy with alias templates:

template<typename T, typename Cmp = std::less<>, typename Alloc = std::allocator<T>>
  using set = std::set<T, Cmp, Alloc>;

名称 is_transparent 来自STL的 N3421 ,它将菱形运算符添加到C ++ 14中。 透明函子是接受任何参数类型(它们不必相同)并简单地将这些参数转发到另一个运算符的函数。这样的函子恰恰是你想要的用于关联容器中的异构查找的,所以将 is_transparent 类型添加到所有菱形算子,并用作标签类型来指示应在关联容器中启用新功能。从技术上讲,容器不需要一个透明函数,只需要支持用异类类型调用它(例如 pointer_comp http://stackoverflow.com/a/18940595/981959 根据STL的定义不透明,但定义 pointer_comp :: is_transparent 允许它用来解决问题)。如果您只查找 std :: set< T,C> 中键类型为 T int , C 只需要可调用 T int (按任意顺序),它不需要是真正的透明。我们使用这个名称部分是因为我们不能提出一个更好的名称(我会优先 is_polymorphic ,因为这样的函子使用静态多态性,但已经有一个 std :: is_polymorphic type trait是指动态多态性)。

The name is_transparent comes from STL's N3421 which added the "diamond operators" to C++14. A "transparent functor" is one which accepts any argument types (which don't have to be the same) and simply forwards those arguments to another operator. Such a functor happens to be exactly what you want for heterogeneous lookup in associative containers, so the type is_transparent was added to all the diamond operators and used as the tag type to indicate the new functionality should be enabled in associative containers. Technically, the containers don't need a "transparent functor", just one that supports calling it with heterogeneous types (e.g. the pointer_comp type in http://stackoverflow.com/a/18940595/981959 is not transparent according to STL's definition, but defining pointer_comp::is_transparent allows it to be used to solve the problem). If you only ever lookup in your std::set<T, C> with keys of type T or int then C only needs to be callable with arguments of type T and int (in either order), it doesn't need to be truly transparent. We used that name partly because we couldn't come up with a better name (I would have preferred is_polymorphic because such functors use static polymorphism, but there's already a std::is_polymorphic type trait which refers to dynamic polymorphism).

这篇关于什么是透明比较器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆