C++17将(可能) 放宽循环范围的定义,允许end()返回一个不同的类型(例如哨兵):
struct MyRange {
struct Sentinel {};
int* begin();
Sentinel end();
};
bool operator!=(int*, MyRange::Sentinel);目前唯一支持这一点的编译器是gcc 6.1和clang 4.0+ (示例) (错误信息示例)。如果我正在编写一个范围类型,其中一个哨兵对结束类型更有效,那么如何检测编译器是否支持轻松的范围?我在P0184R0 (上面链接的)中看不到对此的任何讨论;会提供一个特性测试宏吗?
进一步问题:
end()成员函数的返回类型(对于库)安全吗?我是否需要使我的哨兵隐式转换为我的迭代器类型?sentinel())公开我的哨兵?预C++17算法能有效地使用[begin(), sentinel())还是不值得使用额外的代码?发布于 2016-08-16 14:06:58
根据P0096R3,您可以检查__cpp_range_based_for是否大于或等于201603。当然,Visual不支持任何特性测试宏,因此您必须单独检查其版本。他们在VS2015更新3中提供了对它的支持,但与大多数其他C++17支持一样,您必须使用/std:c++latest交换机。
发布于 2016-08-15 15:04:20
哨兵效率高的原因很少与哨兵的内部状态有关。
因此,一种方法是给您的Sentinel提供足够的内部状态来生成迭代器版本本身。
即使在具有统一的end for(:)循环和坚持相同开始/完成迭代器类型的算法的C++14中,手写算法或循环也可以使用您的哨兵并提高效率。
如果您想要最大的覆盖率,像Boost.Config这样的库通常是最好的选择,但是到目前为止还没有发布C++17特性检测集(我可以找到)。
据我所知,没有任何方法可以检测接受不同开始/结束迭代器类型的for(:)循环的存在。(我可以想象一些constexpr不存在的东西,除了一些黑客,但这超出了我的能力。)
检测<algorithms>是否接受哨兵终末迭代器可能是可以用SFINAE进行的。但我不确定,即使C++17已经对<algorithms>进行了哨兵化,或者甚至打算这样做;ranges v3应该处理这方面的返工。
https://stackoverflow.com/questions/38957468
复制相似问题