作为 std::initializer_list 对象的抽象类

2023-12-24

为了有更清晰的语法,我想使用std::初始化列表将对象列表发送到构造函数。然而,这些对象是抽象的,这会导致一个问题:在 VS 2013 中,它丢失了 vfptr 引用,给出了“R6025:纯虚函数调用“运行时错误,在 g++ 中它抱怨它”无法分配抽象类型“base”的对象“在编译期间。我推测编译器正在尝试复制对象(这是不希望的 - 它们可能很大),但仅在复制基类时成功,因此出现错误。我的问题是:是否有一个解决方案(1 ) 避免复制对象,并且 (2) 不是非常冗长,否定了“更干净的语法”优势?下面的代码说明了我的问题:

#include <cstdio>
#include <initializer_list>

struct base{
    virtual void foo() const = 0;
};

struct derived : public base{
    int i;
    derived(int i) : i(i) {}
    void foo() const{
        printf("bar %i", i);
    }
};

void foo_everything(const std::initializer_list<base> &list){
    for (auto i = list.begin(), iend = list.end(); i != iend; i++) i->foo();
}

int main(void){

    // Works fine
    derived d(0);
    base * base_ptr = &d;
    base_ptr->foo();    

    // Does not work fine
    foo_everything({ derived(1), derived(2), derived(3) });
}

请注意,在模板中使用 base& 会出现错误,因为 std::initializer_list 尝试“[形成] 指向引用类型基数的指针&”,在使用 base* 时,然后获取每个派生类的地址实际上是有效的,它是通过获取临时变量的地址来实现的,因此不安全(g++ 抱怨)。如果我这样做,后者确实可以工作在方法调用之外声明派生类(我的临时解决方案),但它仍然比我希望的更详细。


使用有点黑客的方法initializer_list<base *>:

template<class... Ts>
void foo_everything(Ts&&... args){
    std::initializer_list<base *> list = {&args...};
    for(auto i : list) i->foo();
}

然后从调用中删除大括号:

foo_everything(derived(1), derived(2), derived(3));

如果您确实不需要转换为base *并执行虚拟呼叫,并且只想呼叫foo()对于传入的每个对象,我们可以使用通常的 pack-expansion-inside-an-initializer-list 技巧:

template<class... Ts>
void foo_everything(Ts&&... args){
    using expander = int[];
    (void) expander { 0, ((void) std::forward<Ts>(args).foo(), 0)...};
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

作为 std::initializer_list 对象的抽象类 的相关文章

  • CMake 找不到请求的 Boost 库

    既然我已经浏览了其他人的解决方案几个小时 但找不到适合我的问题的正确答案 我想将我的具体问题带给您 我正在尝试使用 CMake 构建 vsomeip 为此 我之前构建了 boost 1 55 但是 我在 CMake 中收到以下错误 The
  • 将 new 与 decltype 一起使用

    T t T is an implementation detail t new T want to avoid naming T to allow for flexibility t new decltype t error cannot
  • 您可以从基本 Win32 控制台模板应用程序中的 C#/Winrt 组件调用(不是 WinForm/abstractions/wrappers 或使用 C++/Winrt 模板)吗?)

    我有一个现有的程序 win32 x86 控制台应用程序 需要调用托管代码 来自 Net 的 C dll The dll不暴露给 COM 但可以从 C WinRT 组件调用并由 C WinRT 控制台模板应用引用 BUT即使安装了 C Win
  • Poco c++Net:Http 从响应中获取标头

    我使用 POCO C Net 库进行 http 我想尝试制定持久缓存策略 首先 我认为我需要从缓存标头中获取过期时间 并与缓存值进行交叉检查 如果我错了 请告诉我 那么我如何从中提取缓存头httpResponse 我已经看到你可以用 Jav
  • 为什么 F# 的默认集合是排序的,而 C# 的不是?

    当从 C 世界迁移到 F 最惯用的可能 思维方式时 我发现了这个有趣的差异 在 C 的 OOP mutable 世界中 默认的集合集合似乎是HashSet https learn microsoft com en us dotnet api
  • 如何在另一个应用程序中挂钩 api 调用

    我正在尝试挂钩另一个应用程序的 ExtTextOut 和 DrawTextExt GDI 方法调用 我知道我需要使用 GetProcAddress 来查找 gdi32 dll 中那些方法的地址 并用我的函数的地址覆盖我想要挂钩的进程中的地址
  • 在现代 C++ 中,临时生命周期延长何时有用?

    在 C 中 您可以将函数的返回值 返回值 而不是引用 绑定到 const 引用 并且代码仍然有效 因为该临时对象的生命周期将延长到作用域末尾 例如 std string get string return abc void f const
  • 解析 JWT 令牌以仅获取有效负载内容,无需 C# 或 Blazor 中的外部库

    我正在使用 Blazor 编写可以访问 JWT 的客户端应用程序 我想知道一种简单的方法来读取令牌有效负载内容而不添加额外的依赖项 因为我不需要其他信息 也不需要验证令牌 我认为解析有效负载内容应该足够简单 只需将其写入方法即可 JwtTo
  • 在开关中使用“goto”?

    我看到了一个建议的编码标准 内容如下Never use goto unless in a switch statement fall through 我不跟 这个 例外 案例到底是什么样的 这证明了goto 此构造在 C 中是非法的 swi
  • Gwan C#,如何获取HTTP标头?

    我需要它来重写 url 以了解我正在处理哪个友好的 url 用于用户代理和其他东西 EDIT public class Gwan MethodImplAttribute MethodImplOptions InternalCall exte
  • MFC:如何设置CEdit框的焦点?

    我正在开发我的第一个简单的 MFC 项目 但我正在努力解决一个问题 想要设置所有的焦点CEdit其中一个对话框中的框 我的想法是 当打开对话框时 焦点位于第一个编辑框上 然后使用 选项卡 在它们之间交换 我看到了方法SetFocus 但我无
  • 将接口转换为其具体实现对象,反之亦然?

    在 C 中 当我有一个接口和几个具体实现时 我可以将接口强制转换为具体类型 还是将具体类型强制转换为接口 这种情况下的规则是什么 Java 和 C 中都允许这两个方向 向下转型需要显式转型 如果对象类型不正确 可能会抛出异常 然而 向上转换
  • UI 函数在快速事件完成之前触发

    我有一个停靠在 Silverlight 应用程序中的 Web 浏览器框架 有时会在其上弹出全窗口 XAML Silverlight UI 元素 我已经或多或少修复了一个老问题 即 Web 框架的内容似乎与 Silverlight 内容不能很
  • 析构函数中的异步操作

    尝试在类析构函数中运行异步操作失败 这是代码 public class Executor public static void Main var c1 new Class1 c1 DoSomething public class Class
  • 如何使用 NPOI 按地址(A1、A2)获取 Excel 单元格值

    我有一个 Excel 单元格地址 例如 A1 A2 如何使用 C 中的 NPOI 框架以编程方式访问此单元格 我找到的一些 Java POI 示例代码 CellReference cr new CellReference A1 row my
  • 如何从 Rx Subscribe 回调异步函数?

    我想回调 Rx 订阅中的异步函数 例如 像那样 public class Consumer private readonly Service service new Service public ReplaySubject
  • Linux mremap 不释放旧映射?

    我需要一种方法将页面从一个虚拟地址范围复制到另一个虚拟地址范围 而无需实际复制数据 范围很大 延迟很重要 mremap 可以做到这一点 但问题是它也会删除旧的映射 由于我需要在多线程环境中执行此操作 因此我需要旧映射能够同时使用 因此稍后当
  • 如何调试 .NET 运行时中的内部错误?

    我正在尝试调试一些处理大文件的工作 代码本身works 但 NET 运行时本身会报告零星错误 对于上下文 这里的处理是一个 1 5GB 文件 仅加载到内存中一次 在循环中处理和释放 故意尝试重现此否则不可预测的错误 我的测试片段基本上是 t
  • 需要提取字符串中点后的最后一个数字,如“7.8.9.1.5.1.100”

    我需要提取 C 字符串中最后一个点后面的最后一个数字 例如 7 8 9 1 5 1 100 并将其存储在整数中 Added 该字符串也可以是 7 8 9 1 5 1 1 或 7 8 9 1 5 1 0 我还想验证它在最后一个点之前恰好是 7
  • DataContractSerializer 事件/委托字段问题

    在我的 WPF 应用程序中 我正在使用DataContractSerializer序列化对象 我发现它无法序列化具有事件或委托声明的类型 考虑以下失败的代码 Serializable public abstract class BaseCl

随机推荐

  • 使用 gradle 时无法推断 groovy 类路径

    我有一个简单的 Gradle 项目 apply plugin groovy apply plugin application mainClassName HelloWorld 包含一个 Groovy 源文件src main groovy p
  • 如何从 ARKit 录制视频?

    现在我正在测试 ARKit SceneKit 实现 屏幕的基本渲染有点工作 所以我想尝试将我在屏幕上看到的内容记录到视频中 只是为了记录我发现的场景套件这个要点 https gist github com lacyrhoades 7eb42
  • svn_load_dirs.pl 有替代品吗?

    我们有一个大供应商分支机构 http svnbook red bean com en 1 4 svn book html svn advanced vendorbr 1200 个奇怪的文件 最近经历了一些重要的更改 我想将其重新集成到主干中
  • 在 Android 活动之间共享全局 facebook 对象

    我正在创建一个全局 Facebook 对象 来自 android facebook sdk 以便能够在我的活动中共享它 public class GlobalVars extends Application public static fi
  • 没有足够的权限来安装服务

    我的服务声明如下
  • Python有内置函数可以生成从0到1的100个数字吗?

    我正在寻找类似的东西range 但它允许我指定开始值和结束值 以及我想以类似方式使用的集合中需要多少个数字range用于for loops Python 没有浮点范围函数 但您可以使用列表推导式轻松模拟浮点范围函数 gt gt gt lo
  • 如何使用 purrr 从嵌套列表中选择具有相同名称的元素?

    require purrr list lt list node list a list y 1 t 1 b list y 1 t 2 node list a list y 1 t 3 b list y 1 t 4 如何用 purrr 选择所
  • 当仅需要接触检测时,我可以使用 SKAction 移动动态物理体吗?

    我正在查看教程 其中的内容定义如下 飞机是具有动态物理体的精灵 平面移动是通过遵循路径的动作来完成的 子弹与飞机接触检测 子弹是精灵 它的物理主体设置为静态 在我看来这没什么不寻常的 这是链接tutorial http code tutsp
  • NTLM 对 Savon 的支持

    我正在使用 Savon 通过 Web 服务与 SharePoint 进行通信 如果 SharePoint Web 应用程序支持基本身份验证 则一切正常 但如果我将其更改为 NTLM 则会失败 它在线失败 newclient http aut
  • 如何在 alpine 中使用最新版本的 chromium 驱动程序

    我们使用 Alpine 作为运行 watir 测试的 docker 容器 我想使用较新的版本 例如 chromium75 0 3770 8 和 chromium chromedriver75 0 3770 8 但 Alpine 最新版本是
  • 从 Silverlight 调用 Javascript 函数

    我正在尝试从 silverlight 控件调用 javascript 函数 在我们的代码中 我试图通过以下方式调用该函数 HtmlPage Window Invoke showPopup new string http www exampl
  • 如何按日期对 SVN LS -R 输出进行排序

    我想列出 svn 中的所有文件 按上次提交日期排序 svn ls Rv列出所有文件 但不接受 t转变 有谁知道如何做到这一点 我看过一个答案类似的问题 https stackoverflow com questions 22235391 s
  • 如何对管道中的布尔值取反?

    考虑以下代码 defmodule T do def does not contain s t do s gt not String contains t end end 这会在编译时出现以下错误 CompileError iex 3 und
  • 屏幕关闭/锁定后手机振动停止工作

    我有一项服务可以检查我的网站上的更新 我希望它能够在发现更新时引起振动 即使屏幕关闭或锁定也是如此 目前 振动仅在屏幕未关闭 锁定时起作用 即使屏幕关闭 锁定 所有其他功能也可以工作 Vibrator vibrator Vibrator g
  • 如何在 perl 中将字符串转换为文件句柄?

    我有一根非常大的绳子 s dfasdfasdfafd 近百万字 我想将其转换为文件句柄 使其看起来像是从文件中读取的字符串 但我不想将其存储到临时文件中并读取它 有人可以给我一些建议吗 打开对字符串的引用 use strict use wa
  • 我可以在 HTML 文件正文中放置 标记以通过电子邮件发送吗?

    由于许多电子邮件客户端忽略 HEAD 标签 我可以在正文中嵌入内联样式表吗 最简洁的答案是不 Gmail 会删除标签及其内容 Hotmail 雅虎 邮件和 Windows Live Mail 不会删除正文元素中的样式标签 但看看适用于 HT
  • 使用 ptrace 提取系统调用名称和参数

    我正在做一项必须执行的任务strace喜欢使用功能ptrace 到目前为止 我已经找到了如何提取系统调用号和返回值 如下所示 In parent process struct user regs struct regs ptrace PTR
  • Python:编译源代码中的导入错误

    我在运行编译的源代码时遇到问题 代码本身是正确的 如果我运行python file py一切顺利 如果我用 pyinstaller 或类似的软件编译它 然后运行它说的编译文件ImportError No module named cffi
  • 撤消从错误的 github 存储库中拉取的操作

    我刚刚从 github 拉取 然后从错误的 github 存储库拉取到我的项目中 我该如何撤消这个操作 Thanks git reset hard HEAD 此命令将您的分支重置为上一个提交 即合并提交之前的提交 这是您要撤消的提交 您的工
  • 作为 std::initializer_list 对象的抽象类

    为了有更清晰的语法 我想使用std 初始化列表将对象列表发送到构造函数 然而 这些对象是抽象的 这会导致一个问题 在 VS 2013 中 它丢失了 vfptr 引用 给出了 R6025 纯虚函数调用 运行时错误 在 g 中它抱怨它 无法分配