过滤范围、lambda 和 is_sorted

2024-04-13

这是我在过滤迭代器方面遇到的问题的简化版本(因此没有必要要求我以不同的方式重写它以避免过滤器)。奇怪的是,仅在真实代码中is_sorted似乎有问题,其他用途似乎工作正常。

#include <vector>
#include <boost/range/adaptor/filtered.hpp>
#include <boost/range/algorithm_ext/is_sorted.hpp>

int main(int argc, const char* argv[])
{
  using namespace boost::adaptors;
  std::vector<int> all = {1,2,3,4,5,6,7,8,9};
  auto some = all | filtered([] (int i) { return i % 2; });
  return boost::is_sorted(some);
}

这无法使用 Clang++ 3.5 和 G++ 4.9 进行编译(在 Mac OS X 上,最新):

$ clang++-mp-3.5 -std=c++11 -isystem /opt/local/include/ foo.cc
In file included from foo.cc:3:
In file included from /opt/local/include/boost/range/algorithm_ext/is_sorted.hpp:18:
/opt/local/include/boost/detail/is_sorted.hpp:25:28: error: object of type
      'boost::filter_iterator<(lambda at foo.cc:9:30), std::__1::__wrap_iter<int
      *> >' cannot be assigned because its copy assignment operator is
      implicitly deleted
  for (; it != last; first = it, ++it)
                           ^
...

/opt/local/include/boost/iterator/filter_iterator.hpp:106:17: note: copy
      assignment operator of 'filter_iterator<(lambda at foo.cc:9:30),
      std::__1::__wrap_iter<int *> >' is implicitly deleted because field
      'm_predicate' has a deleted copy assignment operator
      Predicate m_predicate;
                ^
foo.cc:9:30: note: lambda expression begins here
  auto some = all | filtered([] (int i) { return i % 2; });
                             ^

我知道将我的 lambda 存储在std::function修复了它,但我想避免付款 它的价格。使用自定义包装器std::is_sorted并不能解决问题。这个问题似乎与其他问题有关(例如,boost 变换迭代器和 c++11 lambda https://stackoverflow.com/questions/12672372/), 但事实并非如此——至少他们的治疗方法在这里不适用。

Thanks!


Inside is_sorted用于迭代序列的迭代器被复制,以便它可以用于比较相邻元素。这意味着谓词filtered(即您的 lambda)也需要复制,即使它从未实际用于增加尾随迭代器。其他复制迭代器的算法也会有同样的问题,例如adjacent_find.

复制迭代器的算法与不复制迭代器的算法之间的区别在于,前者被称为“多遍”算法,并且要求其迭代器类型满足ForwardIterator http://en.cppreference.com/w/cpp/concept/ForwardIterator,而后者是单遍的,只需要InputIterator.

解决方案是给你的 lambda 局部作用域生命周期并传递它reference_wrapper http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper:

auto odd = [] (int i) { return i % 2; };
auto some = all | filtered(std::ref(odd));

另一种方法是使用以下命令将 lambda 强制转换为函数指针+ https://stackoverflow.com/questions/18889028/a-positive-lambda-what-sorcery-is-this?lq=1:

auto some = all | filtered(+[] (int i) { return i % 2; });

不过,这只适用于无捕获的 lambda,并且可能不清楚。

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

过滤范围、lambda 和 is_sorted 的相关文章

  • JSON.Net 反序列化返回“null”

    我正在使用 JSON Net 反序列化 JSON 字符串 JSON 字符串是 string testJson Fruits Apple color red size round Orange Pro
  • C free() 是如何工作的? [复制]

    这个问题在这里已经有答案了 可能的重复 malloc 和 free 如何工作 https stackoverflow com questions 1119134 how malloc and free work include
  • 如果 JSON.NET 中的值为 null 或空格,则防止序列化

    我有一个对象需要以这样的方式序列化 即 null 和 空白 空或只是空格 值都不会序列化 我不控制对象本身 因此无法设置属性 但我知道所有属性都是字符串 环境NullValueHandling显然 忽略 只能让我找到解决方案的一部分 它 似
  • 通过 C# Mailkit / Mimekit 发送电子邮件,但出现服务器证书错误

    Visual Studio 2015 中的 0 代码 1 我正在使用 Mailkit 最新版本 1 18 1 1 从我自己的电子邮件服务器发送电子邮件 2 电子邮件服务器具有不受信任的自签名证书 3 我在代码中添加了以下两行 以忽略服务器证
  • 用于连接 DataTable 上的动态列的动态 LINQ

    我目前遇到的情况不确定如何继续 我有两个从数据库填充的数据表 我还有一个可用的列名称列表 可用于将这两个数据表连接在一起 我希望编写一组 LINQ 查询 这些查询将 显示两个数据表中的行 内部联接 用于从一个数据表更新另一个数据表 显示一个
  • 如何使用递归查找数字中的最小元素 [C]

    好的 所以我正在准备我的 C 考试 当谈到递归时我有点卡住了我是大学一年级的学生 这对我来说似乎有点困难 练习要求在给定的数字中使用递归函数我需要找到最小的元素 例如 52873 是 2 程序需要打印 2 include
  • Xamarin - SignalR 挂在连接上

    我正在尝试将我的 Xamarin 应用程序连接到托管在 Azure 上的 SignalR 后端 我遇到的问题是每次我在 HubConnection 上调用 StartAsync 时 它都会挂起客户端并且请求永远不会完成 我尝试通过应用程序进
  • 时间:2019-03-17 标签:c++fstream并发访问

    如果从不同的进程 线程同时访问文件会发生什么 据我所知 没有锁定文件的标准方法 只有操作系统特定的功能 就我而言 文件将被经常读取而很少写入 现在如果A打开一个文件进行读取 ifstream 并开始读取块 和B打开相同的文件进行写入 ofs
  • Resharper:IEnumerable 的可能多重枚举

    我正在使用新的 Resharper 版本 6 在我的代码中的几个地方 它给一些文本加了下划线 并警告我可能存在IEnumerable 可能的多重枚举 我理解这意味着什么 并在适当的情况下采纳了建议 但在某些情况下 我不确定这实际上是一个大问
  • 如何在 C# 中获取 Json 数组?

    我有一个像这样的 Json 字符串 我想将它加载到 C 数组中 当我尝试这样做时 我收到异常 我的字符串 customerInformation customerId 123 CustomerName Age 39 Gender Male
  • 无法为 wsdl 文件创建服务引用

    I have wsdl文件和xsd我本地机器上的文件 我想在项目中添加服务引用 我没有网络服务 我只有wsdl file 我收到以下错误 The document was understood but it could not be pro
  • 为什么 f(i = -1, i = -1) 是未定义的行为?

    我正在读关于违反评估顺序 http en cppreference com w cpp language eval order 他们举了一个令我困惑的例子 1 如果标量对象上的副作用相对于同一标量对象上的另一个副作用是无序的 则行为未定义
  • 无法在 C# 中为 EventArgs 分配使用派生类型的事件处理程序

    所以我有一个事件声明如下 public event EventHandler OnChangeDetected 然后我有以下处理程序被分配给该事件 myObject OnChangeDetected OnTableChanged 我的理解是
  • 使用 xslt 将 xml 转换为 xsl-fo 时动态创建超链接?

    我想使用 xsl 文件在 PDF 报告中创建标题 如果源文件包含超链接 则应将其呈现为超链接 否则呈现为纯文本 例如 我的 xml 如下所示 a href http google com target blank This is the h
  • “必须声明标量变量”错误[重复]

    这个问题在这里已经有答案了 必须声明标量变量 Id SqlConnection con new SqlConnection connectionstring con Open SqlCommand cmd new SqlCommand cm
  • 无法识别解决方案文件夹中的 Visual Studio 2017 Nuget.config

    我在使用 Visual Studio 2017 时遇到问题 新的解决方案不断引用 C Users yopa AppData Roaming NuGet Nuget config 中意外位置的 Nuget config 文件 我已将 nuge
  • 如果“嵌入式”SQL 2008 数据库文件不存在,如何创建它?

    我使用 C ADO Net 和在 Server Management Studio 中创建的嵌入式 MS SQL 2008 数据库文件 附加到 MS SQL 2008 Express 创建了一个数据库应用程序 有人可以向我指出一个资源 该资
  • 这种尺寸对齐是如何工作的

    对于所提供的评论 我无法理解以下代码 这段代码的作用是什么 以及等效的代码是什么8 aligned segment size must be 4 aligned attr gt options ssize 3 Here ssize is o
  • 为什么表达式 a = a + b - ( b = a ) 在 C++ 中给出序列点警告?

    以下是测试代码 int main int a 3 int b 4 a a b b a cout lt lt a lt lt a lt lt lt lt b lt lt b lt lt n return 0 编译此命令会出现以下警告 gt g
  • C++ Boost ASIO 简单的周期性定时器?

    我想要一个非常简单的周期性计时器每 50 毫秒调用我的代码 我可以创建一个始终休眠 50 毫秒的线程 但这很痛苦 我可以开始研究用于制作计时器的 Linux API 但它不可移植 I d like使用升压 我只是不确定这是否可能 boost

随机推荐