当前位置: 首页 > 知识库问答 >
问题:

ADL和容器函数(开始、结束等)

方苗宣
2023-03-14

C 11及更高版本在命名空间std中定义自由函数开始结束等。对于大多数容器,这些函数调用相应的成员函数。但对于某些容器(如valray),这些自由函数被重载(initializer_list没有成员开始())。因此,要遍历任何容器自由函数,并从std以外的命名空间中查找容器的函数,应使用ADL:

 template<typename C>
 void foo(C c)
 {
   using std::begin;
   using std::end;
   using std::empty;

   if (empty(c)) throw empty_container();
   for (auto i = begin(c); i != end(c); ++i) { /* do something */ }
 }

问题1:我说得对吗?是否希望通过ADL找到开始和结束?

但ADL规则规定,若参数的类型是类模板专门化,则ADL包括所有模板参数的名称空间。然后再升压。范围库开始发挥作用,它定义了boost::begin、boost::end等。这些函数定义如下:

template< class T >
inline BOOST_DEDUCED_TYPENAME range_iterator<T>::type begin( T& r )
{
    return range_begin( r );
}

如果我使用标准向量

问题2:在这种情况下我该怎么办?

依靠成员函数的存在?最简单的方法。

禁止Boost。范围采用容器而不是一对迭代器的算法非常方便。促进范围适配器(将算法延迟应用于容器的容器)也很方便。但如果我不使用Boost。在我的代码中,它仍然可以在boost库中使用(范围除外)。这使得模板代码非常脆弱。

禁止Boost?

共有1个答案

汪飞捷
2023-03-14

几年前,我遇到了一个类似的问题,我的代码突然在std::begin和boost::begin之间变得模棱两可。我发现这是因为使用了Boost。运算符来帮助定义类,即使它甚至不是公共基类或对所涉及类型的用户来说很明显。在某处引起的随机更改包括

我向邮件列表抱怨将类直接放在Boost命名空间中,而不是嵌套类中,并使用声明通过公开它们;直接在Boost命名空间中定义的所有内容都可能通过意外ADL相互踩踏。

我今天刚刚试着复制这个,它现在似乎对这种含糊不清的东西很有弹性!查看定义,boost::begin本身位于内部名称空间中,因此如果您没有使用boost::begin提供自己的,则无法通过无条件查找找到它 在您自己的范围内。

我不知道这是多久前的事了。(如果您仍然可以复制,请发布一个完整的程序,其中包含版本和平台详细信息。)

对于Boost,不要再担心了(如果需要,升级Boost)。

对于新代码,切勿在与其定义的任何类型相同的命名空间中定义名为begin的自由函数。

 类似资料:
  • 7. 直播开始/结束,/录制结束回调通知 7.1. 功能 通知客户直播已开始/结束,此接口为我方调用客户的接口,告知客户直播过程已开始(或结束) 7.2. 地址 由客户提供 7.3. 请求参数 直播结束参数: 必须有的参数: 流名,liveId(场次号),开始时间,结束时间 其它参数:推流端IP,推流URL 录制结束参数: 必须有的参数: 流名,liveId(场次号),开始时间,结束时间,状态(录

  • 我有一个类似于以下内容的DataFrame(sqlDF)(在本例中进行了简化),其中我试图删除在另一行的开始日期和结束日期范围内具有start_date和end_date的所有行: 首先,最终用户要求我删除start_date和end_date之间间隔小于5天的所有记录,我使用了以下方法: 从而产生如下所示的数据frame: 现在,我需要筛选出开始日期和结束日期在同一id的另一行开始日期和结束日期

  • 在这个指南中你学习了关于思考、设计和构建动画的基础。我记得当我第一次进入动画开发并让我的第一个对象在屏幕上移动的时候,它完全使我震惊了。它真的改变了我,和我的工作。我不再是仅仅将静止的app模型放到Photoshop中,或者在Keynote或其他工具中做一些可点击的模型,我真的构建了可以运行在我的手机的上界面!那是2008年,在真正酷的弹簧动画框架出现之前,所以当时只是使用了简单的淡入淡出。现在,

  • 我想使用excel来跟踪多年来我每个月有多少实习生。 有没有一种方法,我可以使用excel列出每个实习生工作的月数,如下所示,以便我能够将我每月有多少实习生放入图表中 感谢您的帮助!提前感谢:)

  • 问题内容: 我需要Java中本月的开始日期和结束日期。当JSP页面加载了当前月份时,它将自动计算该月份的开始和结束日期。它应该与年份和月份无关。也就是说某个月有31天或30天或28天。这也应该满足a年。你能帮我吗? 例如,如果我在列表框中选择“五月”,则需要开始日期为1,结束日期为31。 问题答案: 你去了: PS:类只是两个值的一对。