是否可以/建议返回一个范围?

2024-04-24

我正在使用范围库来帮助我的类中的文件管理器数据,如下所示:

class MyClass
{
public:
    MyClass(std::vector<int> v) : vec(v) {}

    std::vector<int> getEvens() const
    {
        auto evens = vec | ranges::views::filter([](int i) { return ! (i % 2); });
        return std::vector<int>(evens.begin(), evens.end());
    }

private:
    std::vector<int> vec;
};

在这种情况下,一个新的向量被构建在getEvents()功能。为了节省这种开销,我想知道是否可以/建议直接从函数返回范围?

class MyClass
{
public:
    using RangeReturnType = ???;

    MyClass(std::vector<int> v) : vec(v) {}

    RangeReturnType getEvens() const
    {
        auto evens = vec | ranges::views::filter([](int i) { return ! (i % 2); });
        // ...
        return evens;
    }

private:
    std::vector<int> vec;
};

如果可能的话,我是否需要考虑任何终生注意事项?

我也有兴趣知道是否可以/建议将范围作为参数传递,或将其存储为成员变量。或者范围库更适合在单个函数的范围内使用?


这是在op的评论部分提出的,但我想我会在答案部分回应:

Ranges 库看起来很有前途,但我对这个返回的汽车有点担心。

请记住,即使添加auto,C++是一种强类型语言。就你而言,既然你要回来evens,那么返回类型将与evens。 (从技术上讲,它将是evens, but evens无论如何都是一个值类型)

In fact, you probably really don't want to type out the return type manually: std::ranges::filter_view<std::ranges::ref_view<const std::vector<int>>, MyClass::getEvens() const::<decltype([](int i) {return ! (i % 2);})>> (141 characters)


  • 正如 @Caleth 在评论中提到的,事实上,这也不起作用evens是在函数内部定义的 lambda,即使两个不同的 lambda 基本相同,其类型也会不同,因此实际上无法在此处获取完整的返回类型。

虽然对于是否使用可能存在争议auto或在不同情况下不使用,但我相信大多数人都会使用auto这里。再加上你的evens被宣布为auto同样,输入类型只会降低这里的可读性。


那么,如果我想访问子集(例如偶数),我有什么选择?无论是否有 Ranges 库,我还应该考虑其他方法吗?

根据您访问返回数据的方式和数据类型,您可能会考虑返回std::vector<T*>.

views确实应该从头到尾看一遍。虽然你可以使用views::drop and views::take为了限制为单个元素,它还没有提供下标运算符。

计算上也会存在差异。vector需要预先计算,其中views是在迭代时计算的。所以当你这样做时:

for(auto i : myObject.getEven())
{
    std::cout << i;
}

在幕后,它基本上在做:

for(auto i : myObject.vec)
{
    if(!(i % 2)) std::cout << i;
}

取决于数据量和计算的复杂性,views可能会快很多,或者与vector方法。此外,您可以轻松地在同一范围内应用多个过滤器,而无需多次迭代数据。

最后,您可以随时存储view in a vector:

std::vector<int> vec2(evens.begin(), evens.end());

所以我的建议是,如果你有范围库, 然后你should use it.

If not, then vector<T>, vector<T*>, vector<index> depending on the size and copiability of T.

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

是否可以/建议返回一个范围? 的相关文章

  • 更新 Azure Blob 上的 LastModified

    我正在移植代码以使用 C 中的 Azure 存储 SDK 传统上 我称其为更新修改文件的上次写入 修改时间 File SetLastWriteTimeUtc fileName lastWriteTimeUtc 要更新 blob 的上次修改时
  • 信号与信号2

    我的应用程序可能会受益于使用 boost 的信号库之一而不是本土解决方案 该应用程序是多线程的 但执行信号处理的部分是单线程的 如果多线程不是问题 是否有任何理由更喜欢 Boost Signals2 而不是 Boost Signal Boo
  • C# 中类似图的实现

    所以我有一个对象 我们称之为 Head 它有一个对象列表 C C1 C2 C3 T T1 T2 和 M M1 M2 并且所有这些都是相互关联的 例如 Head gt C1 C2 C3 T1 T2 M1 M2 T1 gt C1 C2 T2 g
  • 对 ExecuteNonQuery() 的单次调用是原子的

    对 ExecuteNonQuery 的单次调用是否是原子的 或者如果单个 DbCommand 中有多个 sql 语句 那么使用事务是否有意义 请参阅我的示例以进行说明 using var ts new TransactionScope us
  • 如何使用c#从数据桶中获取所有文档?

    如何获取数据桶中的所有文档 我尝试过一个示例 但我只能获得一个特定的文档 这是我的代码 CouchbaseClient oclient oclient new CouchbaseClient vwspace data bucket name
  • 预编译头和 Visual Studio

    有没有办法设置 Visual Studio 解决方案参数 以便它只创建预编译头而不构建整个解决方案 具体来说 它是一个巨大的 C 解决方案 本身有许多项目 谢谢 仅选择 pch 创建者源文件 通常是 stdafx cpp 然后编译该文件 C
  • 无法将参数从 `const char *` 转换为 `char *`

    鉴于此代码 void group build int size std string ips Build the LL after receiving the member list from bootstrap head new memb
  • 在 .NET Core 中从 HttpResponseMessage 转换为 IActionResult

    我正在将之前在 NET Framework 中编写的一些代码移植到 NET Core 我有这样的事情 HttpResponseMessage result await client SendAync request if result St
  • 如何使用 CUDA/Thrust 对两个数组/向量根据其中一个数组中的值进行排序

    这是一个关于编程的概念问题 总而言之 我有两个数组 向量 我需要对一个数组 向量进行排序 并将更改传播到另一个数组 向量中 这样 如果我对 arrayOne 进行排序 则对于排序中的每个交换 arrayTwo 也会发生同样的情况 现在 我知
  • asp.net core http 如果没有内容类型标头,则删除 `FromBody` 忽略

    我在 http 中使用 bodyDELETE要求 我知道目前删除主体是非标准的 但是允许的 使用时出现问题HttpClient它不允许删除请求的正文 我知道我可以使用SendAsync 但我宁愿让我的 API 更加灵活 我希望这个机构是可选
  • 节点*链表中的下一个

    我是数据结构和算法的新手 我遇到了以下代码 typedef struct node int data node next 谁能告诉我为什么我们要声明节点 next next 不能声明为 int next 吗 因为你希望能够做到n gt ne
  • 如何禁用基于 ValidationRule 类的按钮?

    如何禁用基于 ValidationRule 类的 WPF 按钮 下面的代码可以很好地突出显示 TextBox
  • 在 C# .NET 中对非 ASCII 字符进行编码

    我想向我的应用程序发送的电子邮件添加自定义标头 标头名称只能包含 ASCII 字符 但对于值和用户可能会输入 UTF 8 字符 我必须对它们进行 Base64 编码 此外 我还必须将它们解码回 UTF 8 以便在 UI 中向用户显示它们 最
  • 应在堆栈上分配的最大数量

    我一直在寻找堆栈溢出有关应在堆栈上分配的最大内存量的指南 我看到了堆栈与堆分配的最佳实践 但没有关于应该在堆栈上分配多少以及应该在堆上分配多少的指南 有什么想法 数字可以作为指导吗 什么时候应该在堆栈上分配 什么时候应该在堆上分配 多少才算
  • 意外的 const 引用行为

    include
  • 基础设施 - 同步和异步接口和实现? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 在实现库 基础设施时 并且该 API 的用户希望同步和异步使用代码 我读到混合同步和异步并不是一个好主意 例如 同步实现包括等待异步实现 显然
  • 如何在控制台程序中获取鼠标位置?

    如何在 Windows 控制台程序中用 C 获取鼠标单击位置 点击时返回鼠标位置的变量 我想用简单的文本命令绘制一个菜单 这样当有人点击时 游戏就会注册它并知道位置 我知道如何做我需要做的一切 除了单击时获取鼠标位置 您需要使用 Conso
  • 为什么 C++ 标准没有将 sizeof(bool) 定义为 1?

    Size of char signed char and unsigned char由 C 标准本身定义为 1 个字节 我想知道为什么它没有定义sizeof bool also C 03 标准 5 3 3 1 说 sizeof char s
  • 使用C标准数学库精确计算标准正态分布的CDF

    标准 C 数学库不提供计算标准正态分布 CDF 的函数 normcdf 然而 它确实提供了密切相关的函数 误差函数 erf 和互补误差函数 erfc 计算 CDF 的最快方法通常是通过误差函数 使用预定义常量 M SQRT1 2 来表示 d
  • C# PasswordDeriveBytes:似乎 Salt 并不重要

    可能我误解了什么 以下代码通过 CryptDeriveKey 使用两种不同的盐生成两个相等的密钥 这是控制台结果 盐1 21 3e 18 a3 9a 8b 5f gt 键 da 89 ea 3d 91 08 20 98 20 e9 dc 4

随机推荐