模拟基于范围的 for 循环的开始/结束行为

2024-02-13

考虑基于范围的 for 循环的规范开始表达式 and end-expr(N4140 [stmt.ranged]/p1)。给定一个范围__range类型的_RangeT,

开始表达式 and end-expr确定如下:

  • if _RangeT是一个数组类型,开始表达式 and end-expr are __range and __range + __bound,分别是,其中__bound是 数组绑定。如果_RangeT是一个未知大小的数组或一个数组 不完整类型,程序格式不正确;
  • if _RangeT是一个类类型,不合格的 IDs begin and end在类范围内查找_RangeT就像通过类成员访问一样 查找(3.4.5),并且如果其中一个(或两者)找到至少一个 宣言,开始表达式 and end-expr are __range.begin() and __range.end(), 分别;
  • 否则,开始表达式 and end-expr are begin(__range) and end(__range),分别是,其中begin and end被查找于 关联的命名空间 (3.4.2)。 [Note:普通不合格 不执行查找(3.4.1)。 —end note ]

是否可以模拟这个exact普通 C++ 代码中的行为?即,我们可以写一个magic_begin and a magic_end函数模板使得

for(auto&& p : range_init) { /* statements */ }

and

{
    auto&& my_range = range_init;
    for(auto b = magic_begin(my_range), e = magic_end(my_range); b != e; ++b){
        auto&& p = *b;
        /* statements */
    }
}

总是有完全相同的行为?

无应答包括合格的呼叫std::begin/std::end(不处理第三个项目符号等)并且using std::begin; begin(range);因为除其他外,如果 ADL 为begin找到一个同样好的重载std::begin.


为了便于说明,给出

namespace foo {
    struct A { int begin; }; 
    struct B { using end = int; };
    class C { int* begin(); int *end(); }; // inaccessible
    struct D { int* begin(int); int* end();};
    struct E {};

    template<class T> int* begin(T&) { return nullptr; }
    template<class T> int* end(T&) { return nullptr; }
}

foo::A a; foo::B b; foo::C c; foo::D d; foo::E e;

I want magic_begin(a)/magic_begin(b)/magic_begin(c)/magic_begin(d)是一个编译错误,并且magic_begin(e)回来(int*)nullptr.


以下 SFINAE 友好方法似乎可以按预期工作(有关例外情况,请参见下文):

#include <type_traits>

namespace detail {
    struct empty {};
    template <typename T>
    using base = std::conditional_t<std::is_class<T>{} && not std::is_final<T>{},
                                    T, empty>;

    struct P1 {typedef int begin, end;};
    template <typename U>
    struct TestMemType : base<U>, P1 {
        template <typename T=TestMemType, typename=typename T::begin>
        static std::true_type test_begin(int);
        template <typename T=TestMemType, typename=typename T::end>
        static std::true_type test_end(int);

        static std::false_type test_begin(float), test_end(float);
    };

    template <typename T>
    constexpr bool hasMember = !decltype(TestMemType<T>::test_begin(0)){}
                            || !decltype(TestMemType<T>::test_end(0)){};

    //! Step 1
    template <typename T, std::size_t N>
    constexpr auto begin(int, T(&a)[N]) {return a;}
    template <typename T, std::size_t N>
    constexpr auto end(int, T(&a)[N]) {return a+N;}

    //! Step 2 - this overload is less specialized than the above.
    template <typename T>
    constexpr auto begin(int, T& a) -> decltype(a.begin()) {return a.begin();}
    template <typename T>
    constexpr auto end(int, T& a) -> decltype(a.end()) {return a.end();}

    //! Step 3
    namespace nested_detail {
        void begin(), end();
        template <typename T>
        constexpr auto begin_(T& a) -> decltype(begin(a)) {return begin(a);}
        template <typename T>
        constexpr auto end_(T& a) -> decltype(end(a)) {return end(a);}
    }
    template <typename T, typename=std::enable_if_t<not hasMember<std::decay_t<T>>>>
    constexpr auto begin(float, T& a) -> decltype(nested_detail::begin_(a))
    {return nested_detail::begin_(a);}
    template <typename T, typename=std::enable_if_t<not hasMember<std::decay_t<T>>>>
    constexpr auto end(float, T& a) -> decltype(nested_detail::end_(a))
    {return nested_detail::end_(a);}
}

template <typename T>
constexpr auto magic_begin(T& a) -> decltype(detail::begin(0, a))
{return detail::begin(0, a);}
template <typename T>
constexpr auto magic_end  (T& a) -> decltype(detail::end  (0, a))
{return detail::  end(0, a);}

Demo http://coliru.stacked-crooked.com/a/3c8514f56c017396。请注意,GCC 查找已损坏,因为它不考虑非类型名称typename T::begin in TestMemType::test_end/begin。可以找到解决方法草图here http://coliru.stacked-crooked.com/a/8abb2f9761f4ea34.

步骤 2 中的检查要求类类型是可派生的,这意味着该方法不能正确使用final类或联合 - 如果它们具有无法访问的成员名称begin/end.

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

模拟基于范围的 for 循环的开始/结束行为 的相关文章

  • 根据属性的类型使用文本框或复选框

    如果我有这样的结构 public class Parent public string Name get set public List
  • 机器Epsilon精度差异

    我正在尝试计算 C 中双精度数和浮点数的机器 epsilon 值 作为学校作业的一部分 我在 Windows 7 64 位中使用 Cygwin 代码如下 include
  • 如何在 C# 中打开 Internet Explorer 属性窗口

    我正在开发一个 Windows 应用程序 我必须向用户提供一种通过打开 IE 设置窗口来更改代理设置的方法 Google Chrome 使用相同的方法 当您尝试更改 Chrome 中的代理设置时 它将打开 Internet Explorer
  • free 和 malloc 在 C 中如何工作?

    我试图弄清楚如果我尝试 从中间 释放指针会发生什么 例如 看下面的代码 char ptr char malloc 10 sizeof char for char i 0 i lt 10 i ptr i i 10 ptr ptr ptr pt
  • -webkit-box-shadow 与 QtWebKit 模糊?

    当时有什么方法可以实现 webkit box shadow 的工作模糊吗 看完这篇评论错误报告 https bugs webkit org show bug cgi id 23291 我认识到这仍然是一个问题 尽管错误报告被标记为RESOL
  • 无限循环与无限递归。两者都是未定义的吗?

    无副作用的无限循环是未定义的行为 看here https coliru stacked crooked com view id 24e0a58778f67cd4举个例子参考参数 https en cppreference com w cpp
  • 使用 C# 中的 CsvHelper 将不同文化的 csv 解析为十进制

    C 中 CsvHelper 解析小数的问题 我创建了一个从 byte 而不是文件获取 csv 文件的类 并且它工作正常 public static List
  • WcfSvcHost 的跨域异常

    对于另一个跨域问题 我深表歉意 我一整天都在与这个问题作斗争 现在已经到了沸腾的地步 我有一个 Silverlight 应用程序项目 SLApp1 一个用于托管 Silverlight SLApp1 Web 的 Web 项目和 WCF 项目
  • 结构体的内存大小不同?

    为什么第一种情况不是12 测试环境 最新版本的 gcc 和 clang 64 位 Linux struct desc int parts int nr sizeof desc Output 16 struct desc int parts
  • C# - 当代表执行异步任务时,我仍然需要 System.Threading 吗?

    由于我可以使用委托执行异步操作 我怀疑在我的应用程序中使用 System Threading 的机会很小 是否存在我无法避免 System Threading 的基本情况 只是我正处于学习阶段 例子 class Program public
  • 为什么使用小于 32 位的整数?

    我总是喜欢使用最小尺寸的变量 这样效果就很好 但是如果我使用短字节整数而不是整数 并且内存是 32 位字可寻址 这真的会给我带来好处吗 编译器是否会做一些事情来增强内存使用 对于局部变量 它可能没有多大意义 但是在具有数千甚至数百万项的结构
  • 如何实例化 ODataQueryOptions

    我有一个工作 简化 ODataController用下面的方法 public class MyTypeController ODataController HttpGet EnableQuery ODataRoute myTypes pub
  • 编译时展开 for 循环内的模板参数?

    维基百科 here http en wikipedia org wiki Template metaprogramming Compile time code optimization 给出了 for 循环的编译时展开 我想知道我们是否可以
  • C# 中的 IPC 机制 - 用法和最佳实践

    不久前我在 Win32 代码中使用了 IPC 临界区 事件和信号量 NET环境下场景如何 是否有任何教程解释所有可用选项以及何时使用以及为什么 微软最近在IPC方面的东西是Windows 通信基础 http en wikipedia org
  • 使用特定参数从 SQL 数据库填充组合框

    我在使用参数从 sql server 获取特定值时遇到问题 任何人都可以解释一下为什么它在 winfom 上工作但在 wpf 上不起作用以及我如何修复它 我的代码 private void UpdateItems COMBOBOX1 Ite
  • 当文件流没有新数据时如何防止fgets阻塞

    我有一个popen 执行的函数tail f sometextfile 只要文件流中有数据显然我就可以通过fgets 现在 如果没有新数据来自尾部 fgets 挂起 我试过ferror and feof 无济于事 我怎样才能确定fgets 当
  • MySQL Connector C/C API - 使用特殊字符进行查询

    我是一个 C 程序 我有一个接受域名参数的函数 void db domains query char name 使用 mysql query 我测试数据库中是否存在域名 如果不是这种情况 我插入新域名 char query 400 spri
  • 指针和内存范围

    我已经用 C 语言编程有一段时间了 但对 C 语言还是很陌生 有时我对 C 处理内存的方式感到困惑 考虑以下有效的 C 代码片段 const char string void where is this pointer variable l
  • 现代编译器是否优化乘以 1 和 -1

    如果我写 template
  • 使用 WGL 创建现代 OpenGL 上下文?

    我正在尝试使用 Windows 函数创建 OpenGL 上下文 现代版本 基本上代码就是 创建窗口类 注册班级 创建一个窗口 choose PIXELFORMATDESCRIPTOR并设置它 创建旧版 OpenGL 上下文 使上下文成为当前

随机推荐

  • SwiftUI 更新地图区域导致有关修改状态的警告

    我有一个使用 iOS 14 中新的 SwiftUI Map 的项目 我希望能够动态更新地图中心的位置 当您点击 缩放 按钮 然后点击 位置 按钮时 地图可以正常工作并重新以伦敦为中心 但是 如果您只是点击位置按钮 它会重新以伦敦为中心 但会
  • Sublime Text - 转到行和列

    目前 转到行快捷方式 Windows Linux 中的 CTRL G 仅允许导航到特定行 最好选择允许在逗号后指定列号 例如 30 11转到第 30 行 第 11 列 是否有任何插件或自定义脚本可以实现此目的 Update 3 这是现在Su
  • 使用Python在NLP中的命名实体识别中提取人名

    我有一个句子需要单独识别人名 例如 sentence Larry Page is an American business magnate and computer scientist who is the co founder of Go
  • 从本机应用程序到网站的切换不起作用

    我的设备 iPad Mini 最新 iOS 8 dp5 Macbook Air 优胜美地 dp5 我在上述两个设备之间进行了切换 Safari 邮件 消息 日历等所有切换都没有问题 我什至可以在 Air 上的网站和 iPad 上的本机应用程
  • 如何在qt中获取联系人列表

    我使用此代码并仅获取一个人的联系方式 contactManager new QContactManager QList
  • 如何从 C++ 打开 URL?

    如何从我的 C 程序中打开 URL 在红宝石中你可以做 x open https google com C 中的等价物是什么 我想知道是否有一个独立于平台的解决方案 但如果没有 我更喜欢 Unix Mac 这是我的代码 include
  • ReadToEnd 之后关闭 StreamReader

    在构造中调用 ReadToEnd 方法后是否可以以某种方式关闭 StreamReader 如下所示 string s new StreamReader filename Encoding UTF8 ReadToEnd 任何具有相同语义的替代
  • Visual Studio 2010/2012 Git 插件

    我正在寻找 git 与 VS 2010 2012 集成的建议 允许开发人员使用基本操作 提交 推送 拉取 切换分支 标记 有几个 Git 源代码控制提供程序 http visualstudiogallery msdn microsoft c
  • 在多层应用程序中,是否应该允许客户端将自己的 linq 表达式发送到服务器?

    理由 HQL 和 NH 标准是 NHibernate 特定的构造 因此它们是服务器端 DAL 实现细节 我不希望它们 泄漏 到客户端 因此 我们的客户端提供LINQ表达式供服务器处理 对我来说似乎合理 但是有些人不这么认为 所以我想知道为什
  • 简单 XML 框架反序列化的异常

    我在反序列化已成功序列化的 XML 文件时遇到问题简单的 XML 序列化 http simple sourceforge net 框架 simpleframework org 有一个例外 http simple sourceforge ne
  • Firefox 扩展在 main.js 文件中包含脚本

    我正在为 Firefox 编写扩展 但在将脚本包含到 main js 后台 文件中时遇到问题 就我而言 我想包括 jquery js 和 config js 但我不知道如何正确执行它 在我的 chrome 扩展中 我只是在清单文件上执行此操
  • Kafka Streams代理连接超时设置

    我们正在使用 kafka streams 2 3 1 我刚刚注意到 如果代理关闭 流应用程序似乎会满足于尝试永远尝试连接 new KafkaStreams createTopology properties start o apache k
  • 如何修复“W293 空白行包含空格”

    我的 python 代码产生以下警告消息 1 dir file py 8 1 W293 blank lines contains whitespace this comes after commands 0 flake8 XXX 你如何解决
  • 矢量瓦片路线查找

    有人使用 Mapbox 或 OpenMapTiles 矢量切片来查找从一个地方到另一个地方的路线吗 在我看来 这些图块是为了显示而制作的 并不像开放街道地图那样包含交叉路口信息 地图盒有路线API https www mapbox com
  • 如何清除 Angular JS 的文件输入

    在 AngularJS 中 我使用此处描述的方法来处理输入 type file https groups google com forum fromgroups topic angular OpgmLjFR U https groups g
  • 用 * 屏蔽掉字符串的前 12 个字符?

    我怎样才能取值123456789012345 or 1234567890123456并将其变成 2345 and 3456 上面两个字符串的区别在于 一个包含 15 位数字 另一个包含 16 位数字 我已经尝试过以下操作 但它不会保留 15
  • HttpServletRequest UTF-8 编码 [重复]

    这个问题在这里已经有答案了 我想从请求中获取参数 带重音符号的字符 但它不起作用 我尝试使用request setCharacterEncoding UTF 8 但它也不起作用 我知道URLDecoder decode request ge
  • 如果未找到,Regexp.match.length 返回 NULL

    我有一个 JS 正则表达式 var t1 str match h1 g length If str包含这个词 h1 它工作正常 否则显示错误 如何解决问题 var t1 str match h1 g length
  • 如何在asp.net mvc项目中使用Material-UI

    有没有一种方法可以使用 Material UI 而无需使用 NodeJS 安装所有依赖项 我很想在 ASP NET 项目中使用它 但不知道从哪里开始安装依赖项以及所有这些 从技术上讲 在没有任何前端基础设施的情况下使用 Material U
  • 模拟基于范围的 for 循环的开始/结束行为

    考虑基于范围的 for 循环的规范开始表达式 and end expr N4140 stmt ranged p1 给定一个范围 range类型的 RangeT 开始表达式 and end expr确定如下 if RangeT是一个数组类型