IEEE 浮点数是 std::map 和 std::set 的有效键类型吗?

2024-01-04

背景

关联容器(例如 std::map)的键类型上的比较器的要求是它对键类型的元素施加严格的弱顺序。

对于给定的比较器comp(x, y)我们定义equiv(x, y) = !comp(x, y) && !comp(y, x).
要求comp(x, y)是一个严格的弱秩序

  1. 缺乏灵活性(!comp(x, x)对全部x)
  2. 排序的传递性(如果comp(a, b) and comp(b, c) then comp(a, c)).
  3. 等价的传递性(如果equiv(a, b) and equiv(b, c) then equiv(a, c))

std::less<float>(默认比较器)使用operator<,这不会创建严格的弱顺序,因为NaN。因为x < NaN and NaN < x对所有人来说都是假的x, NaN相当于该比较器下的所有浮点数,这打破了条件#3:equiv(1.0, NaN) and equiv(NaN, 2.0)但不是equiv(1.0, 2.0)。对于除 NaN 之外的 IEEE 浮点数,它是严格的弱顺序(其中每个数字都有自己的等价类,除了0 and -0).

问题

这是否意味着由于上述问题,C++ 标准不允许使用 IEEE 浮点(和(长)双精度)作为关联容器中的键类型,即使我确保 NaN 永远不会插入到容器中?我不太确定“元素”Key标准中的措辞 - 如果它表示所有可能的元素或仅表示最终出现在容器中的元素。

注意:这个问题与问题无关。截断/舍入,我可能很快就会发布一个与此相关的不同问题。

Update:

Sigh。我应该在不指定浮动的情况下提出问题,我只是认为这是一个很好的例子。

问题确实是:是否允许使用一个比较器,该比较器仅对放入容器中的元素施加严格的弱顺序,而不是对键类型的所有可能实例施加严格的弱顺序?请不要只回答“是”或“否”,我想要一些关于此问题的标准/先前讨论/来自委员会成员的答案或其他内容的参考。


我怀疑这些限制应该被视为指关系对实际用作键的值的行为,而不一定是针对该类型的所有值。目前没有时间通过​​标准寻找引用实际容器元素而不是该类型的所有值的“确凿证据”语言。

类似的情况:如果比较器(用于指针或智能指针的容器)调用虚函数,并且有人链接它所比较类型的派生类,这会以某种方式覆盖虚函数,使比较器不是严格的弱函数,该怎么办命令?即使没有人真正使用该派生类,程序是否也会变得未定义?

如果有疑问,您可以使用严格弱阶比较器来支持 NaN:

bool operator()(double a, double b) {
    if ((a == a) && (b == b)) {
        return a < b;
    }
    if ((a != a) && (b != b)) return false;
    // We have one NaN and one non-NaN.
    // Let's say NaN is less than everything
    return (a != a)
}

最后两行“优化”为return (b == b);,尽管我不确定评论是否会随之优化。

我认为托马拉克已经说服了我,该语言确实表明整个类型都需要订购。

这没有什么意义,因为地图不会凭空产生值,它只使用给定的值(及其副本),但问题是关于规则,据我所知,它们是规则。 C++0x 是一样的。我想知道是否有缺陷报告,或者是否有任何提交缺陷报告的地方。

这也很烦人,因为在(非常罕见的)系统上std::less对于指针来说很慢,你can't use <作为指针映射中的比较器,即使您知道指针都指向同一数组的元素。耻辱。

另一种选择是使用以下类作为键类型,因此仅在进入映射时检查键是否为 NaN,而不是在上面的每次比较时检查键。

struct SaneDouble {
    double value;
    SaneDouble (double d) : value(d) {
        if (d != d) throw std::logic_error();
    }
    static friend bool operator<(SaneDouble lhs, SaneDouble rhs) {
        return lhs.value < rhs.value;
    }
    // possibly a conversion to double
};

这提出了另一个问题——显然有人可以创建一个SaneDouble然后设置它的valueNaN(假设实现允许他们从某处获取一个而不崩溃)。那么“SaneDouble 的元素”是否是严格弱序的?我半心半意地尝试在构造函数中创建一个类不变量是否会使我的程序未定义,即使没有人真正破坏该不变量,仅仅是因为他们could因此这样做的结果是“SaneDouble 的元素”?当且仅当定义程序的行为时,这真的是标准的意图吗?value被标记private?该标准实际上是否在任何地方定义了类型的“元素”?

我想知道我们是否应该将“Key 的元素”解释为比较器对 Key 的某些元素产生严格的弱顺序。大概包括实际使用的。 “我有甜甜圈”并不意味着我有every油炸圈饼。不过,这有点牵强。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

IEEE 浮点数是 std::map 和 std::set 的有效键类型吗? 的相关文章

  • OpenCv读/写视频色差

    我试图简单地使用 openCV 打开视频 处理帧并将处理后的帧写入新的视频文件 我的问题是 即使我根本不处理帧 只是打开视频 使用 VideoCapture 读取帧并使用 VideoWriter 将它们写入新文件 输出文件看起来比输入更 绿
  • C#动态支持吗?

    看完之后这个帖子 https stackoverflow com questions 2674906 when should one use dynamic keyword in c sharp 4 0k和链接 我还有 2 个问题 问题 1
  • 以编程方式检查页面是否需要基于 web.config 设置进行身份验证

    我想知道是否有一种方法可以检查页面是否需要基于 web config 设置进行身份验证 基本上如果有这样的节点
  • 构造函数中显式关键字的使用

    我试图了解 C 中显式关键字的用法 并查看了这个问题C 中的explicit关键字是什么意思 https stackoverflow com questions 121162 但是 那里列出的示例 实际上是前两个答案 对于用法并不是很清楚
  • 对齐 GridView 中的行值

    我需要在 asp net 3 5 中右对齐 gridview 列中的值 我怎样才能做到这一点
  • 如何使用recv()检测客户端是否仍然连接(并且没有挂起)?

    我写了一个多客户端服务器程序C on SuSE Linux 企业服务器 12 3 x86 64 我为每个客户端使用一个线程来接收数据 我的问题是 我使用一个终端来运行服务器 并使用其他几个终端来运行服务器telnet到我的服务器 作为客户端
  • 如何配置 WebService 返回 ArrayList 而不是 Array?

    我有一个在 jax ws 上实现的 java Web 服务 此 Web 服务返回用户的通用列表 它运行得很好 Stateless name AdminToolSessionEJB RemoteBinding jndiBinding Admi
  • 从多个类访问串行端口

    我正在尝试使用串行端口在 arduino 和 C 程序之间进行通信 我对 C 编程有点陌生 该程序有多种用户控制形式 每一个都需要访问串口来发送数据 我需要做的就是从每个类的主窗体中写入串行端口 我了解如何设置和写入串行端口 这是我的 Fo
  • 检查算术运算中的溢出情况[重复]

    这个问题在这里已经有答案了 可能的重复 检测 C C 中整数溢出的最佳方法 https stackoverflow com questions 199333 best way to detect integer overflow in c
  • 如何从网站下载 .EXE 文件?

    我正在编写一个应用程序 需要从网站下载 exe 文件 我正在使用 Visual Studio Express 2008 我正在使用以下代码 private void button1 Click object sender EventArgs
  • Azure 事件中心 - 按顺序接收事件

    我使用下面的代码从 Azure Event Hub 接收事件 https learn microsoft com en us azure event hubs event hubs dotnet framework getstarted s
  • 基于xsd模式生成xml(使用.NET)

    我想根据我的 xsd 架构 cap xsd 生成 xml 文件 我找到了这篇文章并按照说明进行操作 使用 XSD 文件生成 XML 文件 https stackoverflow com questions 6530424 generatin
  • 如何重置捕获像素的值

    我正在尝试创建一个 C 函数 该函数返回屏幕截图位图中每四个像素的 R G 和 B 值 这是我的代码的一部分 for int ix 4 ix lt 1366 ix ix 4 x x 4 for int iy 3 iy lt 768 iy i
  • 如何在c#中的内部类中访问外部类的变量[重复]

    这个问题在这里已经有答案了 我有两个类 我需要声明两个类共有的变量 如果是嵌套类 我需要访问内部类中的外部类变量 请给我一个更好的方法来在 C 中做到这一点 示例代码 Class A int a Class B Need to access
  • 通过 NHibernate 进行查询,无需 N+1 - 包含示例

    我有一个 N 1 问题 我不知道如何解决它 可以在这个问题的底部找到完全可重复的样本 因此 如果您愿意 请创建数据库 设置 NUnit 测试和所有附带的类 并尝试在本地消除 N 1 这是我遇到的真实问题的匿名版本 众所周知 这段代码对于帮助
  • 将代码拆分为标头/源文件

    我从 Asio 的示例页面中获取了以下代码 class tcp connection public boost enable shared from this
  • 结构体指针的动态数组

    我必须使用以下代码块来完成学校作业 严格不进行任何修改 typedef struct char firstName char lastName int id float mark pStudentRecord pStudentRecord
  • WinRT 定时注销

    我正在开发一个 WinRT 应用程序 要求之一是应用程序应具有 定时注销 功能 这意味着在任何屏幕上 如果应用程序空闲了 10 分钟 应用程序应该注销并导航回主屏幕 显然 执行此操作的强力方法是在每个页面的每个网格上连接指针按下事件 并在触
  • 使用 CSharpCodeProvider 类编译 C# 7.3 的 C# 编译器版本是什么?

    我想使用 Microsoft CSharp CSharpCodeProvider 类来编译 C 7 3 代码 编译器版本在 IDictionary 中指定 在创建新的 CSharpCodeProvider 时将其作为输入 例如 Compil
  • Googletest:如何异步运行测试?

    考虑到一个包含数千个测试的大型项目 其中一些测试需要几分钟才能完成 如果按顺序执行 整套测试需要一个多小时才能完成 通过并行执行测试可以减少测试时间 据我所知 没有办法直接从 googletest mock 做到这一点 就像 async选项

随机推荐

  • 使用 Spark 运行纱线不适用于 Java 8

    我的集群有 1 个主节点和 6 个从节点 它使用预构建版本的 hadoop 2 6 0 和 Spark 1 6 2 我在所有节点上安装 openjdk 7 时运行 hadoop MR 和 Spark 作业 没有任何问题 但是 当我在所有节点
  • sfinae 使用 decltype 检查静态成员

    我编写了以下代码来尝试检测类型是否具有静态成员变量 不幸的是 它总是返回该变量不存在 有人能告诉我哪里出错了吗 我正在使用 g 4 7 1 include
  • VueJS - 使用 vue-test-utils 进行单元测试给出错误 - TypeError: _vm.$t 不是函数

    对于 Vuejs 来说相对较新并正在测试其组件 使用 vue test utils 和 jest 进行测试 出现以下错误test log https i stack imgur com rQejp jpg vue 文件由模板 组件和样式组成
  • 为什么在 golang 中仅初始化定义中的一个变量会失败

    在调用具有以下签名的库函数时 func New sql DB Sqlmock error 像这样 suite db suite mock err sqlmock New inside a suite method 我收到错误 expecte
  • 二值化图像中的单独交叉线段

    我有一些图像处理 允许我提取包含厚片段的二进制图像 并且我面临着这些片段可能相互交叉的问题 因此 我需要找到一种有效的方法来分离它们 我必须在 C 中实现它 这样任何基于 OpenCV 的东西都会有所帮助 这是一个示例输入图像 两个 斑点
  • gcc 是否有任何选项可以在 ELF 二进制文件中添加版本信息?

    我的意思是 gcc 是否可以将一些源代码版本信息作为部分或类似的内容插入到 ELF 二进制文件中 我不想更改我的源文件 但在 Makefile 中使用 gcc 选项添加一些信息 如果您不介意只更改源文件一次 请添加如下内容 const vo
  • 无异常的错误处理

    在搜索与业务规则验证相关的错误处理方法时 我遇到的只是结构化异常处理的示例 MSDN 和许多其他著名的开发资源都非常清楚地表明异常是不用于处理常规错误情况 它们仅用于特殊情况和由于程序员 而非用户 使用不当而可能发生的意外错误 在许多情况下
  • git squash 提交时保留作者信息

    我和我的同事 我们在这里称他为约翰 正在开发一个功能 我们的工作分支如下所示 o o o this is develop branch o o o this is John s branch o o o o o o o this is ou
  • 如何从 SQL Server 中的日期获取月份编号(而不是月份名称)?

    如何在sql中获取月份数 我使用以下代码 但它返回月份名称 SELECT DATENAME mm GETDATE 使用带有 m 扩展名的 datepart 函数 SELECT DATEPART m getdate
  • 内存映射 I/O 与端口映射 I/O [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 子选择与外连接

    考虑以下 2 个查询 select tblA a tblA b tblA c tblA d from tblA where tblA a not in select tblB a from tblB select tblA a tblA b
  • 提供简单的方法来获取当前速度(实现速度计)

    您能否举例说明如何计算当前 速度 我正在开发我的第一个简单应用程序 速度计 我想出用didUpdateToLocation 我还发现我需要使用公式speed distance duration 这样对吗 如何计算持续时间 您需要执行的基本步
  • 为什么我在此 Cocoa 代码中收到 isEqualToString 错误?

    我不断收到此错误 替代文本http img514 imageshack us img514 2203 help tif http img514 imageshack us img514 2203 help tif 它是什么 我什至从未调用过
  • iOS:将 UTC 时区转换为设备本地时区

    我正在尝试将以下时区转换为设备本地时区 2013 08 03T05 38 39 590Z 请让我知道如何将其转换为本地时区 我该怎么做 时区可应用于NSDateFormatter https developer apple com libr
  • 如何使用 Selenium 和 Python 定位具有多个类名的元素

    我正在尝试单击类名称等于的以下元素 clean right li class clean right li 我怎样才能通过使用找到它driver find element by class name 您不能将多个类名作为参数传递find e
  • PHP中的文件上传到mysql

    所以我搜索了一些通过php表单将文件下载到mysql的方法 这是我发现的 www w3schools com php php file upload asp http www w3schools com php php file uploa
  • 无法使用 Rhino Mocks 模拟具有数组参数的构造函数的类

    我们无法在 RhinoMocks 中模拟此类 public class Service public Service Command commands public abstract class Command Code var mock
  • MediaCodec 和 24 位 PCM

    我成功地使用 MediaCodec 解码音频 但是当我加载包含 24 位样本的文件时 我无法知道发生了这种情况 由于应用程序假设使用 16 位样本 因此它失败了 当我打印 MediaFormat 时 我看到 mime audio raw d
  • Kivy 中的错误“修订格式必须为 X.Y.Z[-tag]”

    我尝试运行 mi 程序 但由于某种原因我看到此错误 修订格式必须是 X Y Z tag 我不知道这意味着什么 我一直试图从我的代码中取出一些东西来了解导致它的原因 但我还没有弄清楚 这是我的 python 文件 usr bin python
  • IEEE 浮点数是 std::map 和 std::set 的有效键类型吗?

    背景 关联容器 例如 std map 的键类型上的比较器的要求是它对键类型的元素施加严格的弱顺序 对于给定的比较器comp x y 我们定义equiv x y comp x y comp y x 要求comp x y 是一个严格的弱秩序 缺