如何将“外部模板”与由同一类中的模板化成员使用的嵌套类一起使用?

2024-05-20

首先,一些背景信息:我尝试以 Herb Sutter 在他的解决方案中介绍的方式使用 Pimpl 习语。得到了#101 http://herbsutter.com/gotw/_101/。这在头文件中看起来像这样:

#include "pimpl_h.h"
class widget {
    class impl;
    pimpl<impl> m;
    // ...
};

实现如下所示:

#include "pimpl_impl.h"
class widget::impl {
    // ...
};

当使用此技术的类使用另一个 Pimpl 类作为其自己的实现时,我试图解决的问题就会出现。它包含“pimpl_impl.h”,因此编译器(在我的例子中为 VC++ 2013)获得了具体模板的知识pimpl <impl>另一个类并尝试隐式实例化它,这当然会导致编译错误,因为它不知道该类的实现。

为了解决这个问题,我在头文件中使用了 C++ 11 的新“外部模板”功能:

#include "pimpl_h.h"
class widget {
    class impl;
    pimpl<impl> m;
    // ...
};
extern template pimpl<widget::impl>;

这应该保证只有编译单元中的显式实例化提供了widget::impl导致实际的实例化。编译没有问题,但 IntelliSense 显示错误:

Error: 'extern template' cannot follow explicit instantiation of class "pimpl<widget::impl>"

由于“外部模板”不能在类声明内部使用,所以我不能写

#include "pimpl_h.h"
class widget {
    class impl;
    extern template pimpl<impl>;
    pimpl<impl> m;
    // ...
};

我想不出任何其他办法。我的问题是:

IntelliSense 是否错误,编译器接受我的代码是否正确?或者只是巧合,VC++ 编译了它,而它不是有效的 C++?

如果我的解决方案不是有效的 C++,我有哪些替代方案?


我想我自己解决了这个问题。标准第 14.7.2.11 条中规定

如果一个实体同时是显式实例化声明和显式实例化声明的主题 在同一个翻译单元中实例化定义,该定义应遵循 宣言。

这可能就是 IntelliSense 所指的。这就是我注意到错误消息显示“...无法跟随explicit实例化...”。显然任何地方都没有显式实例化,只是一个implicit类定义内的实例化widget。所以我认为这是 IntelliSense 内部的错误。在同一段落中,标准说

一个实体,它是显式实例化声明的主题,并且也是 以否则会导致隐式实例化(14.7.1)的方式使用 翻译单元应是显式实例化定义的主题 在程序中的哪个位置;否则程序格式错误,无需诊断。

它不需要(潜在的)隐式实例化和显式实例化声明的任何特定顺序。

此时我也意识到我的解决方案对于我原来的问题来说实际上是矫枉过正的。我不想阻止模板类的隐式实例化宣言 and 定义 of pimpl<impl>,但只有模板类定义 inside pimpl_impl.h. The extern template pimpl<impl>抑制了两者,这解决了我的问题,但做了超出必要的事情。解决方案是声明实际成员pimpl<impl> with extern template并稍后显式实例化它们。

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

如何将“外部模板”与由同一类中的模板化成员使用的嵌套类一起使用? 的相关文章

随机推荐

  • OpenCL 内核在 Nvidia GPU 上每个线程使用多少寄存器?

    我的第一个问题是如何获取 Nvidia GPU 上 OpenCL 内核代码的寄存器使用信息 因为 nvcc 编译器给出了相同的使用信息nvcc ptxas options vCUDA 内核代码的标志 我还从 AMD GPU for Open
  • 我应该在哪个方法中设置 UITextField 的委托?

    在 viewDidLoad 或 init 方法中设置 UITextField 的委托是一个好习惯吗 我尝试在 init 方法中将委托设置为 self 但它没有调用相应的委托方法 当我将代码移动到 viewDidLoad 中时 它注册为将 s
  • 使用 Oracle Sql Developer 生成 DDL 以包含外键

    我尝试了一些使用 SQL Developer 从 Oracle 数据库生成 DDL 的选项 但没有一个符合目的 快速 DDL 选项会产生没有外键约束的 DDL 我很喜欢这种格式 表上的编辑导致 DDL 包括我无法摆脱的存储和日志记录 只是想
  • mac osx 10.8 上的初学者 python

    我正在学习编程 并且一直在使用 Ruby 和 ROR 但我觉得我更喜欢 Python 语言来学习编程 虽然我看到了 Ruby 和 Rails 的优点 但我觉得我需要一种更容易学习编程概念的语言 因此是 Python 但是 我似乎找不到适用于
  • onBackPressed 隐藏 不破坏 Activity

    我知道如何取消后退按键 以便活动 主窗口保持可见 public void onBackPressed return 我的目标是隐藏该活动 但是 在没有完成它的情况下 您如何在 onBackPressed 事件中做到这一点 即我想达到 onP
  • 如何通过 Inno Setup for NetBeans 使用自定义 .iss 文件

    我将 Inno Setup 5 与 NetBeans 8 一起使用 并且我已经能够创建一个安装程序来安装该应用程序C users username local appname 但是我希望将其安装在C Programfiles 我如何在 Ne
  • C 语言中 =+(等于加)是什么意思?

    我碰到 与标准相反 今天在一些 C 代码中 我不太确定这里发生了什么 我在文档中也找不到它 In ancientC 版本 相当于 它的残余物与最早的恐龙骨头一起被发现 例如 B 引入了广义赋值运算符 使用x y to add y to x
  • 为什么java中的for-each循环中需要声明变量

    for 每个循环的通常形式是这样的 for Foo bar bars bar doThings 但如果我想保留 bar 直到循环结束 我可以not使用 foreach 循环 Foo bar null Syntax error on toke
  • Google App Engine 超时:数据存储操作超时,或数据暂时不可用

    这是我每天都会在应用程序日志中看到的一个常见异常 通常每天 5 6 次 流量为 1K 访问 天 db error trying to store stats Traceback most recent call last File base
  • 如何将送货地址复制到帐单地址

    我想知道是否可以将送货地址复制到帐单地址 当用户单击与送货地址相同的复选框时 送货地址值将被复制到账单输入字段 我完成了大部分部分 但我不确定如何将选择菜单 状态 值复制到帐单地址 我真的很感谢任何帮助 My code document r
  • Nexus 7 (2013) 和 Win 7 64 - 尽管检查了许多论坛和在线资源,仍无法安装 USB 驱动程序

    我正在尝试设置 Nexus 7 2013 进行调试 但我在安装 USB 驱动程序的步骤中陷入困境 到目前为止 这是我尝试过的 采取的步骤 在 Nexus 7 2013 上打开调试模式 连接设备至 PC 下载 Google USB 驱动程序于
  • NSPredicate 的 onFormat 字符串

    我想用 id 键对数据进行排序 我如何理解格式字符串的用途NSPredicate格式 我有一个100号的帖子 我的代码 let objectIDs posts map 0 id let predicate NSPredicate forma
  • 使用yield 进行字典理解

    作为一个人为的例子 myset set a b c d mydict item yield join item s for item in myset and list mydict gives as cs bs ds a None b N
  • 如何在 OSX 上安装 numpy 和 scipy?

    我是 Mac 新手 请耐心等待 我现在使用的是雪豹 10 6 4 我想安装numpy和scipy 所以我从他们的官方网站下载了python2 6 numpy和scipy dmg文件 但是 我在导入 numpy 时遇到问题 Library F
  • 使用队列从多个输入文件中统一采样

    我的数据集中的每个类都有一个序列化文件 我想使用队列来加载每个文件 然后将它们放入 RandomShuffleQueue 中 这样我就可以从每个类中获得随机的示例组合 我认为这段代码会起作用 在此示例中 每个文件有 10 个示例 filen
  • NoClassDefFoundError:无法解析:Landroid/support/v7/appcompat/R$styleable

    新手尝试完成 Google 提供的我的第一个应用程序教程 在这个致命异常的过程中 我确实导入了很多随机包来消除许多事情的 无法解析 错误 例如 ActionBarActivity EditText Fragment LayoutInflat
  • 如何通过辅助功能 API 获取当前所选文本的全局屏幕坐标。

    我需要帮助来了解字典应用程序如何在任何应用程序上按 CMD CTRL D 时显示所选文本的以下弹出对话框 我想实施 我的可可应用程序具有相同的功能 我的应用程序将在后台运行 并显示有关所选文本的一些热键的建议 我已经实现了热键捕获 我只需要
  • JS用正则表达式替换数字

    我有元素的标识符 如下所示 form book 1 2 3 我想要的是用其他值替换该标识符中的第二个数字 我将函数 match 与以下正则表达式一起使用 var regexp d d d 但它返回我包含的数组 1 2 3 2 因此 当我尝试
  • 在 iOS 上从 GPS 获取时间

    我正在开发一个跟踪器应用程序 该应用程序需要高精度地了解设备位置 即它使用位置服务并忽略水平精度低于 20 米的位置 CLLocation没有明确声明是否通过 GPS 确定 但是 如果水平精度为 20 米或更好 则可以认为它是来自 GPS
  • 如何将“外部模板”与由同一类中的模板化成员使用的嵌套类一起使用?

    首先 一些背景信息 我尝试以 Herb Sutter 在他的解决方案中介绍的方式使用 Pimpl 习语 得到了 101 http herbsutter com gotw 101 这在头文件中看起来像这样 include pimpl h h