glibcxx STL 在 std::valarray::sum() 的实现中是否不正确?

2023-11-27

我正在玩弄valarrays当我遇到某些问题时,我认为编译器的 STL 实现中存在错误。这是我可以制作的最小示例:

#include <iostream>
#include <string>
#include <vector>
#include <iomanip>
#include <valarray>

using namespace std;

int main()
{
    valarray<int> Y(0xf00d, 1);
    valarray<valarray<int>> X(Y, 1);
    cout << "Y[0]           = " << std::hex << Y[0]       << '\n';
    cout << "X[0][0]        = " << std::hex << X[0][0]    << '\n';
    cout << "X[0].size()    = " << X[0].size()            << '\n';
    cout << "X.sum().size() = " << X.sum().size()         << '\n';
}

这将输出:

$ g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
Y[0]           = f00d
X[0][0]        = f00d
X[0].size()    = 1
X.sum().size() = 0

您可以编译并运行它coliru

为什么我认为这是一个错误?因为根据标准(26.6.2.8)

T sum() 常量;

该函数只能为类型 T 实例化 可以应用哪个运算符+=。该函数返回所有的总和 数组的元素。如果数组的长度为 0,则行为 未定义。如果数组长度为 1,sum() 返回的值 元素 0。否则,返回值通过应用计算 运算符+= 到数组的一个元素和所有其他元素的副本 以未指定的顺序排列数组。

valarray 确实有一个+= 运算符

所以我期望X.sum()具有相同的值X[0]。但显然不是这样的,因为它的大小是0而不是1。

我查看了实施sum()并追溯到这段代码:

  //
  // Compute the sum of elements in range [__f, __l)
  // This is a naive algorithm.  It suffers from cancelling.
  // In the future try to specialize
  // for _Tp = float, double, long double using a more accurate
  // algorithm.
  //
  template<typename _Tp>
    inline _Tp
    __valarray_sum(const _Tp* __f, const _Tp* __l)
    {
      _Tp __r = _Tp();
      while (__f != __l)
        __r += *__f++;
      return __r;
    }

我们了解问题的根源。该代码将总和累加到__r,但不是初始化__rvalarray 中的第一项是默认构造的。 valarray 的默认构造函数创建一个大小为 0 的数组。因此最终结果仍然是一个大小为 0 的 valarray。

我对标准的理解是否有效(glibcxx STL 有一个错误)?或者我应该被纠正?

作为记录,我在 cygwin 下使用 g++ 7.3.0,但它是在 coliru 上复制的,它可能不在 cygwin 下运行...


这对我来说是一个错误。sum()

要求: size() > 0。该函数只能为某种类型实例化T到哪个operator+=可以应用。

and valarray确实有一个operator +=所以它符合资格。它是operator +=

要求: size() == v.size()。如果指示的运算符可以应用于类型 T 的两个操作数,则只能为类型 T 实例化每个运算符。valarray 复合赋值运算符左侧元素的值不依赖于左侧的另一个元素。

所以通过做_Tp __r = _Tp();他们产生一个valarray whose size()不等于元素的大小,因此它不能与它一起使用operator +=。更正确的实现是

  template<typename _Tp>
    inline _Tp
    __valarray_sum(const _Tp* __f, const _Tp* __l)
    {
      _Tp __r = *__f++; // this is okay as the function is requires size > 0.  It is the users responsibility to make sure that is the case
      while (__f != __l)
        __r += *__f++;
      return __r;
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

glibcxx STL 在 std::valarray::sum() 的实现中是否不正确? 的相关文章

随机推荐

  • 自动映射器和不变性

    是否可以将 AutoMapper 与不可变类型一起使用 例如 我的域类型是不可变的 我想将我的视图类型映射到此 我相信不是 但只是想确认这一点 此外 由于最佳实践是让域类型不可变 因此将视图类型映射到域类型时的最佳实践是什么 我通常会手动进
  • Webpack:大小超出建议限制 (244 KiB)

    这是有问题的分支和存储库 https github com Futuratum moon holdings tree dev 您好 我遇到了这个问题 因为我有一个包含大量图像的资产文件夹 我不在乎大小 这对于现代网络用户来说应该是正常的 我
  • PHP 命令行界面出现奇怪的 5 秒停顿(与 mysql/mysqli 扩展有关)

    从命令行 PHP 客户端 Windows 上的 PHP 5 2 执行 PHP 脚本时 我遇到了奇怪的 5 到 7 秒的暂停 在此暂停期间 PHP 脚本似乎 冻结 了一段时间 然后返回到命令提示符 它没有使用任何重要的 CPU 时间 就好像它
  • 使用 java 向 WebService 发出 SOAP 请求

    我对如何通过 java 向 Web 服务发出请求有点困惑 目前我唯一了解的是 Web 服务使用 xml 结构化消息 但我仍然不太明白如何构建我的请求
  • Java 的类型擦除有什么好处?

    我读了一篇tweet今天说 当 Java 用户抱怨类型擦除时 这是很有趣的 这是 Java 唯一正确的事情 而忽略了它出错的所有事情 因此我的问题是 Java 的类型擦除有好处吗 除了向后兼容性和运行时性能方面的 JVM 实现偏好之外 它
  • 错误:ENOENT:express-handlebars 中没有此类文件或目录

    我在用express handlebars在 NodeJS 中加载动态内容 inside app js const express require express const bodyParser require body parser c
  • 嵌入式系统上运行的Java VM推荐

    我们正在尝试在我们的嵌入式平台 700 MHzMIPS 74K 128 256 MB 内存 读完这篇文章后article谷歌搜索了一下 我想出了入围名单 Sun 的 Java ME Kaffe Jbed Perc HP Chai 虚拟机 P
  • 如何在不刷新页面的情况下将新的 HTML 数据从服务器推送到浏览器

    我见过许多网站 例如 Facebook 或 Stack Overflow 它们会在生成新数据时更新某些功能 例如帖子上的新答案 假设博客中添加了一篇新帖子 并且当时有人在博客中查看它 其想法是自动将新帖子添加到博客中 而无需刷新或让用户执行
  • 同时捕获java异常FileNotFound和IOException

    FileNotFoundException 是否是 IOException 的 子异常 这是我的代码 打开给定路径处文件的输入流 method FileInputStream fs try fs new FileInputStream pa
  • 表 xxx' 上的 UPDATE 语句预计更新 1 行; 0 与 Zope transactionmanager 匹配

    我正在运行 Pyramid Zope 事务管理器 SQLAlchemy PostgreSQL 在某些场合 我见过StaleDataErrorPyramid Web 应用程序上的错误 该错误对于更新数据库中的一行来说应该是非常简单的视图 由于
  • Google电子表格:将脚本分配给带有参数的按钮

    我可以成功地将脚本分配给 Google 电子表格中的图像 我的问题是参数传递 我有这个脚本可以在单元格上写入当前时间 function Time cell var d new Date var timeAsString d getHours
  • Spring 转换服务:如何将 String 转换为 List

    我正在使用 Spring 的转换服务 并注册了我自己的转换器 public class MyTypeConverter implements Converter
  • 比较 2 个 wchar_t 数组

    我确信这非常简单 但我来自 C 背景 其中字符串很简单 现在我正在进入非托管世界 我很困惑 本质上 我使用 EnumDisplayDevices 来列出可用的设备 我想要定位特定的适配器 因此我需要将 DeviceString 和 Devi
  • JAXB 非法注释异常

    我是第一次使用 JAXB 在理解它要我做什么时遇到一些问题 我已经设置了一个类 它将成为相当大的 XML 的一部分 该类将表示 XML 文档的 标题 部分 package com somecompany jscentral xml inte
  • 并行集合中 scala 折叠的行为

    让我们多次运行以下代码行 Set 1 2 3 4 5 6 7 par fold 0 结果非常有趣 scala gt Set 1 2 3 4 5 6 7 par fold 0 res10 Int 8 scala gt Set 1 2 3 4
  • Javascript 中的一次迭代中的映射和排序?

    是否可以将数组映射到新数组并同时对其进行排序 而无需迭代两次 一次用于第一个数组上的映射 一次用于第二个数组上的排序 在使用这样的映射方法时 我一直尝试使用匿名函数对其进行排序 var arr 4 2 20 44 6 var arr2 ar
  • Jade 模板,包含中的变量范围

    我正在使用 Jade 没有 Express 仅用于静态 HTML 模板 我将其理解为能够创建部分 意味着范围不是问题 但情况似乎并非如此 我找不到对此使用的任何参考 案件 玉大师 5 html block vars var slug hom
  • 如何在 PHP 中发出 HTTP 请求而不等待响应

    PHP 中有没有办法进行 HTTP 调用而不等待响应 我不在乎回应 我只想做类似的事情file get contents 但在执行其余代码之前不等待请求完成 这对于在我的应用程序中引发某种 事件 或触发长进程非常有用 有任何想法吗 我之前接
  • 如何按行长度排序,然后按字母顺序反转

    我有一大堆 600 多个 搜索和替换术语 我需要将它们作为 sed 脚本在某些文件上运行 问题是搜索项不是正交的 但我认为我可以通过按行长度排序来摆脱它 即首先拉出最长的匹配项 然后按每个长度内的字母顺序排列 所以给定一组未排序的 aaba
  • glibcxx STL 在 std::valarray::sum() 的实现中是否不正确?

    我正在玩弄valarrays当我遇到某些问题时 我认为编译器的 STL 实现中存在错误 这是我可以制作的最小示例 include