首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >可移植的支持放松范围的循环

可移植的支持放松范围的循环
EN

Stack Overflow用户
提问于 2016-08-15 14:51:35
回答 2查看 131关注 0票数 1

C++17将(可能) 放宽循环范围的定义,允许end()返回一个不同的类型(例如哨兵):

代码语言:javascript
复制
struct MyRange {
    struct Sentinel {};
    int* begin();
    Sentinel end();
};
bool operator!=(int*, MyRange::Sentinel);

目前唯一支持这一点的编译器是gcc 6.1和clang 4.0+ (示例) (错误信息示例)。如果我正在编写一个范围类型,其中一个哨兵对结束类型更有效,那么如何检测编译器是否支持轻松的范围?我在P0184R0 (上面链接的)中看不到对此的任何讨论;会提供一个特性测试宏吗?

进一步问题:

  • 如果有一种检测编译器支持的方法,那么更改我的end()成员函数的返回类型(对于库)安全吗?我是否需要使我的哨兵隐式转换为我的迭代器类型?
  • 相反,对于预C++17编译器,是否值得以不同的名称(例如sentinel())公开我的哨兵?预C++17算法能有效地使用[begin(), sentinel())还是不值得使用额外的代码?
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-08-16 14:06:58

根据P0096R3,您可以检查__cpp_range_based_fo‌​r是否大于或等于201603。当然,Visual不支持任何特性测试宏,因此您必须单独检查其版本。他们在VS2015更新3中提供了对它的支持,但与大多数其他C++17支持一样,您必须使用/std:c++latest交换机。

票数 3
EN

Stack Overflow用户

发布于 2016-08-15 15:04:20

哨兵效率高的原因很少与哨兵的内部状态有关。

因此,一种方法是给您的Sentinel提供足够的内部状态来生成迭代器版本本身。

即使在具有统一的end for(:)循环和坚持相同开始/完成迭代器类型的算法的C++14中,手写算法或循环也可以使用您的哨兵并提高效率。

如果您想要最大的覆盖率,像Boost.Config这样的库通常是最好的选择,但是到目前为止还没有发布C++17特性检测集(我可以找到)。

据我所知,没有任何方法可以检测接受不同开始/结束迭代器类型的for(:)循环的存在。(我可以想象一些constexpr不存在的东西,除了一些黑客,但这超出了我的能力。)

检测<algorithms>是否接受哨兵终末迭代器可能是可以用SFINAE进行的。但我不确定,即使C++17已经对<algorithms>进行了哨兵化,或者甚至打算这样做;ranges v3应该处理这方面的返工。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38957468

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档