模拟基于范围的 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 循环的开始/结束行为 的相关文章

  • 如何在列表框项目之间画一条线

    我希望能够用水平线分隔列表框中的每个项目 这只是我用于绘制项目的一些代码 private void symptomsList DrawItem object sender System Windows Forms DrawItemEvent
  • WPF 中的调度程序和异步等待

    我正在尝试学习 WPF C 中的异步编程 但我陷入了异步编程和使用调度程序的困境 它们是不同的还是在相同的场景中使用 我愿意简短地回答这个问题 以免含糊不清 因为我知道我混淆了 WPF 中的概念和函数 但还不足以在功能上正确使用它 我在这里
  • 为什么#pragma optimize("", off)

    我正在审查一个 C MFC 项目 在某些文件的开头有这样一行 pragma optimize off 我知道这会关闭所有以下功能的优化 但这样做的动机通常是什么 我专门使用它来在一组特定代码中获得更好的调试信息 并在优化的情况下编译应用程序
  • vector 超出范围后不清除内存

    我遇到了以下问题 我不确定我是否错了或者它是一个非常奇怪的错误 我填充了一个巨大的字符串数组 并希望在某个点将其清除 这是一个最小的例子 include
  • 如何将单个 char 转换为 int [重复]

    这个问题在这里已经有答案了 我有一串数字 例如 123456789 我需要提取它们中的每一个以在计算中使用它们 我当然可以通过索引访问每个字符 但是如何将其转换为 int 我研究过 atoi 但它需要一个字符串作为参数 因此 我必须将每个字
  • Qt表格小部件,删除行的按钮

    我有一个 QTableWidget 对于所有行 我将一列的 setCellWidget 设置为按钮 我想将此按钮连接到删除该行的函数 我尝试了这段代码 它不起作用 因为如果我只是单击按钮 我不会将当前行设置为按钮的行 ui gt table
  • 从库中捕获主线程 SynchronizationContext 或 Dispatcher

    我有一个 C 库 希望能够将工作发送 发布到 主 ui 线程 如果存在 该库可供以下人员使用 一个winforms应用程序 本机应用程序 带 UI 控制台应用程序 没有 UI 在库中 我想在初始化期间捕获一些东西 Synchronizati
  • 当操作繁忙时,表单不执行任何操作(冻结)

    我有一个使用 C 的 WinForms 应用程序 我尝试从文件中读取一些数据并将其插入数据表中 当此操作很忙时 我的表单冻结并且无法移动它 有谁知道我该如何解决这个问题 这可能是因为您在 UI 线程上执行了操作 将文件和数据库操作移至另一个
  • 将 unsigned char * (uint8_t *) 转换为 const char *

    我有一个带有 uint8 t 参数的函数 uint8 t ihex decode uint8 t in size t len uint8 t out uint8 t i hn ln for i 0 i lt len i 2 hn in i
  • C++ fmt 库,仅使用格式说明符格式化单个参数

    使用 C fmt 库 并给定一个裸格式说明符 有没有办法使用它来格式化单个参数 example std string str magic format 2f 1 23 current method template
  • 将文本叠加在图像背景上并转换为 PDF

    使用 NET 我想以编程方式创建一个 PDF 它仅包含一个背景图像 其上有两个具有不同字体和位置的标签 我已阅读过有关现有 PDF 库的信息 但不知道 如果适用 哪一个对于如此简单的任务来说最简单 有人愿意指导我吗 P D 我不想使用生成的
  • 在 Dynamics CRM 插件中访问电子邮件发件人地址

    我正在编写一个 Dynamics CRM 2011 插件 该插件挂钩到电子邮件实体的更新后事件 阶段 40 pipeline http msdn microsoft com en us library gg327941 aspx 并且在此阶
  • WCF:将随机数添加到 UsernameToken

    我正在尝试连接到用 Java 编写的 Web 服务 但有些东西我无法弄清楚 使用 WCF 和 customBinding 几乎一切似乎都很好 除了 SOAP 消息的一部分 因为它缺少 Nonce 和 Created 部分节点 显然我错过了一
  • C - 直接从键盘缓冲区读取

    这是C语言中的一个问题 如何直接读取键盘缓冲区中的数据 我想直接访问数据并将其存储在变量中 变量应该是什么数据类型 我需要它用于我们研究所目前正在开发的操作系统 它被称为 ICS OS 我不太清楚具体细节 它在 x86 32 位机器上运行
  • 32 位到 64 位内联汇编移植

    我有一段 C 代码 在 GNU Linux 环境下用 g 编译 它加载一个函数指针 它如何执行并不重要 使用一些内联汇编将一些参数推送到堆栈上 然后调用该函数 代码如下 unsigned long stack 1 23 33 43 save
  • Process.Start 阻塞

    我正在调用 Process Start 但它会阻止当前线程 pInfo new ProcessStartInfo C Windows notepad exe Start process mProcess new Process mProce
  • const、span 和迭代器的问题

    我尝试编写一个按索引迭代容器的迭代器 AIt and a const It两者都允许更改容器的内容 AConst it and a const Const it两者都禁止更改容器的内容 之后 我尝试写一个span
  • mysql-connector-c++ - “get_driver_instance”不是“sql::mysql”的成员

    我是 C 的初学者 我认为学习的唯一方法就是接触一些代码 我正在尝试构建一个连接到 mysql 数据库的程序 我在 Linux 上使用 g 没有想法 我运行 make 这是我的错误 hello cpp 38 error get driver
  • ASP.NET MVC 6 (ASP.NET 5) 中的 Application_PreSendRequestHeaders 和 Application_BeginRequest

    如何在 ASP NET 5 MVC6 中使用这些方法 在 MVC5 中 我在 Global asax 中使用了它 现在呢 也许是入门班 protected void Application PreSendRequestHeaders obj
  • C 中的异或运算符

    在进行按位操作时 我在确定何时使用 XOR 运算符时遇到一些困难 按位与和或非常简单 当您想要屏蔽位时 请使用按位 AND 常见用例是 IP 寻址和子网掩码 当您想要打开位时 请使用包含或 然而 XOR 总是让我明白 我觉得如果在面试中被问

随机推荐

  • 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是一个数组类型