C++0x 标准中对导出关键字的最佳解释是什么?

2024-01-12

我知道在最初的C++0x标准中有一个功能叫做export.

但我找不到这个功能的描述或解释。它应该做什么?另外:哪个编译器支持它?


尽管标准 C++ 没有这样的要求,但某些编译器要求所有函数模板都需要在使用它的每个翻译单元中可用。实际上,对于这些编译器,模板函数的主体必须在头文件中可用。重复一遍:这意味着这些编译器不允许在非头文件(例如 .cpp 文件)中定义它们。澄清一下,在 C++ 语言中,这意味着:

// ORIGINAL version of xyz.h
template <typename T>
struct xyz
 {
    xyz();
    ~xyz();
 };

不会对 ctor 和 dtor 的这些定义感到满意:

// ORIGINAL version of xyz.cpp
#include "xyz.h"

template <typename T>
xyz<T>::xyz() {}

template <typename T>
xyz<T>::~xyz() {}

因为使用它:

// main.cpp
#include "xyz.h"

int main()
 {
    xyz<int> xyzint;

    return 0;
 }

会产生错误。例如,使用 Comeau C++,您将得到:

C:\export>como xyz.cpp main.cpp
C++'ing xyz.cpp...
Comeau C/C++ 4.3.4.1 (May 29 2004 23:08:11) for MS_WINDOWS_x86
Copyright 1988-2004 Comeau Computing.  All rights reserved.
MODE:non-strict warnings microsoft C++

C++'ing main.cpp...
Comeau C/C++ 4.3.4.1 (May 29 2004 23:08:11) for MS_WINDOWS_x86
Copyright 1988-2004 Comeau Computing.  All rights reserved.
MODE:non-strict warnings microsoft C++

main.obj : error LNK2001: unresolved external symbol xyz<T1>::~xyz<int>() [with T1=int]
main.obj : error LNK2019: unresolved external symbol xyz<T1>::xyz<int>() [with T1=int] referenced in function _main
aout.exe : fatal error LNK1120: 2 unresolved externals

因为 xyz.cpp 中没有使用 ctor 或 dtor,因此不需要从那里进行实例化。无论好坏,这就是模板的工作原理。

解决这个问题的一种方法是显式请求实例化xyz,在这个例子中xyz<int>。通过暴力方式,可以通过在 xyz.cpp 末尾添加以下行来将其添加到 xyz.cpp 中:

template xyz<int>;

其中要求(全部)xyz<int>被实例化。但这有点错误,因为这意味着每次产生新的 xyz 类型时,都必须修改实现文件 xyz.cpp。避免该文件的侵入性较小的方法是创建另一个文件:

// xyztir.cpp
#include "xyz.cpp" // .cpp file!!!, not .h file!!

template xyz<int>;

这仍然有些痛苦,因为每次产生新的 xyz 时仍然需要手动干预。在一个重要的程序中,这可能是一个不合理的维护需求。

因此,解决这个问题的另一种方法是#include "xyz.cpp"进入 xyz.h 的末尾:

// xyz.h

// ... previous content of xyz.h ...

#include "xyz.cpp"

当然,您可以将 xyz.cpp 的内容逐字带到(剪切并粘贴)到 xyz.h 的末尾,从而摆脱 xyz.cpp;这是文件组织的问题,最终预处理的结果将是相同的,因为 ctor 和 dtor 主体将位于标头中,因此会带入任何编译请求,因为这将使用相应的标头。不管怎样,这都会产生副作用,现在每个模板都在您的头文件中。它可能会减慢编译速度,并可能导致代码膨胀。处理后者的一种方法是将相关函数(在本例中为 ctor 和 dtor)声明为内联函数,因此这需要您在运行示例中修改 xyz.cpp。

顺便说一句,一些编译器还要求某些函数在类内部内联定义,而不是在类外部定义,因此对于这些编译器来说,上面的设置需要进一步调整。请注意,这是一个编译器问题,而不是标准 C++ 问题,因此并非所有编译器都需要此问题。例如,Comeau C++ 没有,也不应该。查看http://www.comeaucomputing.com/4.0/docs/userman/ati.html http://www.comeaucomputing.com/4.0/docs/userman/ati.html有关我们当前设置的详细信息。简而言之,Comeau C++ 支持许多模型,包括一种接近导出关键字的意图(作为扩展)的模型,甚至支持导出本身。

最后,请注意,C++ 导出关键字旨在缓解最初的问题。然而,Comeau C++ 是目前唯一公开支持导出的编译器。看http://www.comeaucomputing.com/4.0/docs/userman/export.html http://www.comeaucomputing.com/4.0/docs/userman/export.html and http://www.comeaucomputing.com/4.3.0/minor/win95+/43stuff.txt http://www.comeaucomputing.com/4.3.0/minor/win95+/43stuff.txt了解一些细节。希望随着其他编译器达到标准 C++ 的兼容性,这种情况将会改变。在上面的例子中,使用export意味着返回到产生链接器错误的原始代码,并进行更改:使用export关键字在xyz.h中声明模板:

// xyz.h

export
// ... ORIGINAL contents of xyz.h ...

xyz.cpp 中的 ctor 和 dtor 将仅通过#includeing xyz.h 导出,它已经这样做了。因此,在这种情况下,您不需要 xyztir.cpp,也不需要 xyz.cpp 末尾的实例化请求,并且不需要将 ctor 或 dtor 手动带入 xyz.h。使用前面显示的命令行,编译器可能会自动为您完成这一切。

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

C++0x 标准中对导出关键字的最佳解释是什么? 的相关文章

  • 在C语言中使用“void”

    我很困惑为什么我们需要通过void转换为 C 函数 int f void return 0 versus int f return 0 什么是正确的做法以及为什么 In C int f 是一种老式的声明 它说f需要固定但未指定数量和类型的参
  • 查找哪些页面不再与写入时复制共享

    假设我在 Linux 中有一个进程 我从中fork 另一个相同的过程 后forking 因为原始进程将开始写入内存 Linux写时复制机制将为进程提供与分叉进程使用的不同的唯一物理内存页 在执行的某个时刻 我如何知道原始进程的哪些页面已被写
  • OpenCv读/写视频色差

    我试图简单地使用 openCV 打开视频 处理帧并将处理后的帧写入新的视频文件 我的问题是 即使我根本不处理帧 只是打开视频 使用 VideoCapture 读取帧并使用 VideoWriter 将它们写入新文件 输出文件看起来比输入更 绿
  • 为什么大多数 C 开发人员使用 Define 而不是 const? [复制]

    这个问题在这里已经有答案了 在许多程序中 define与常量具有相同的用途 例如 define FIELD WIDTH 10 const int fieldWidth 10 我通常认为第一种形式优于另一种形式 它依赖于预处理器来处理基本上是
  • 如何配置 WebService 返回 ArrayList 而不是 Array?

    我有一个在 jax ws 上实现的 java Web 服务 此 Web 服务返回用户的通用列表 它运行得很好 Stateless name AdminToolSessionEJB RemoteBinding jndiBinding Admi
  • 访问者和模板化虚拟方法

    在一个典型的实现中Visitor模式 该类必须考虑基类的所有变体 后代 在许多情况下 访问者中的相同方法内容应用于不同的方法 在这种情况下 模板化的虚拟方法是理想的选择 但目前这是不允许的 那么 模板化方法可以用来解析父类的虚方法吗 鉴于
  • 检查算术运算中的溢出情况[重复]

    这个问题在这里已经有答案了 可能的重复 检测 C C 中整数溢出的最佳方法 https stackoverflow com questions 199333 best way to detect integer overflow in c
  • ASP MVC:服务应该返回 IQueryable 的吗?

    你怎么认为 你的 DAO 应该返回一个 IQueryable 以便在你的控制器中使用它吗 不 您的控制器根本不应该处理任何复杂的逻辑 保持苗条身材 模型 而不是 DAO 应该将控制器返回给视图所需的所有内容 我认为在控制器类中看到查询 甚至
  • 如何识别 WPF 文本框中的 ValidationError 工具提示位置

    我添加了一个箭头来指示工具提示中的文本框 当文本框远离屏幕边缘时 这非常有效 但是当它靠近屏幕边缘时 工具提示位置发生变化 箭头显示在左侧 Here is the Image Correct as expected since TextBo
  • 无法将类型“System.IO.Stream”隐式转换为“Java.IO.InputStream”

    我提到了一些类似的问题 但没有一个涉及IO 当我使用时 我在java中使用了相同的代码Eclipse 那次就成功了 但现在我尝试在中使用这段代码Mono for Android C 它不起作用 我正在尝试运行此代码来创建一个InputStr
  • 如何重置捕获像素的值

    我正在尝试创建一个 C 函数 该函数返回屏幕截图位图中每四个像素的 R G 和 B 值 这是我的代码的一部分 for int ix 4 ix lt 1366 ix ix 4 x x 4 for int iy 3 iy lt 768 iy i
  • C# 中条件编译符号的编译时检查(参见示例)?

    在 C C 中你可以这样做 define IN USE 1 define NOT IN USE 1 define USING system 1 system 1 IN USE 进而 define MY SYSTEM IN USE if US
  • 生产代码中的 LRU 实现

    我有一些 C 代码 需要使用 LRU 技术实现缓存替换 目前我知道两种实现LRU缓存替换的方法 每次访问缓存数据时使用时间戳 最后比较替换时的时间戳 使用缓存项的堆栈 如果最近访问过它们 则将它们移动到顶部 因此最后底部将包含 LRU 候选
  • 为什么我不应该对不是由 malloc() 分配的变量调用 free() ?

    我在某处读到 使用它是灾难性的free删除不是通过调用创建的对象malloc 这是真的 为什么 这是未定义的行为 永远不要尝试它 让我们看看当您尝试时会发生什么free 自动变量 堆管理器必须推断出如何获取内存块的所有权 为此 它要么必须使
  • 将构建日期放入“关于”框中

    我有一个带有 关于 框的 C WinForms 应用程序 我使用以下方法将版本号放入 关于 框中 FileVersionInfo GetVersionInfo Assembly GetExecutingAssembly Location F
  • 获取 2 个数据集 c# 中的差异

    我正在编写一个简短的算法 它必须比较两个数据集 以便可以进一步处理两者之间的差异 我尝试通过合并这两个数据集并将结果更改放入新的数据集来实现此目标 我的方法如下所示 private DataSet ComputateDiff DataSet
  • g++ 对于看似不相关的变量“警告:迭代...调用未定义的行为”

    考虑以下代码strange cpp include
  • 有没有一种简单的方法可以让 Visual Studio 2015 使用特定的 ToolsVersion?

    使用特定版本构建项目或解决方案时msbuild我可以使用以下命令选择早期的 net 工具链 toolsversion or tv switch C Program Files x86 MSBuild 14 0 bin msbuild tv
  • 我在在线程序挑战编译器中遇到演示错误

    include
  • 带重定向标准流的 C# + telnet 进程立即退出

    我正在尝试用 C 做一个 脚本化 telnet 项目 有点类似于Tcl期望 http expect nist gov 我需要为其启动 telnet 进程并重定向 和处理 其 stdin stdout 流 问题是 生成的 telnet 进程在

随机推荐

  • 我怎样才能停止 jQuery Mobile 将样式应用到我的特定表单元素

    是否可以指示 jQuery Mobile 不要设置我的输入框和提交按钮的样式 我很擅长自定义 CSS jQuery 移动脚本将其自己的样式应用于我的所有元素 我尝试的一种解决方法是覆盖我的自定义 CSS 中的这些元素 还有其他功能可以让我执
  • 泵送引理(常规语言)

    我需要一些帮助来解决泵引理问题 L a b c a L lt b L lt c L 这是我到目前为止得到的 y uvw is the string from the pumping lemma 我让 y abbc n n 是泵引理的长度 y
  • 从 R 调用 .NET/C#

    我想使用仅在 NET 中可用的 R API 是否有可用于从 R 调用 NET C 代码的标准方法 如果是这样 我该怎么做 本讨论的读者可能会考虑的另一个选择是rClr 包 https github com jmp75 rClr 我已经研究了
  • 实体框架 CTP5,代码优先。可选的导航属性

    我正在使用实体框架 CTP5 代码优先 并且我有两个类 public class Order public int Id get set public decimal SomeOtherProperty1 get set navigatio
  • AWS Elastic Beanstalk NodeJS 和日志

    我想将我的 NodeJS 项目从单个 EC2 迁移到 ElasticBeanstalk 在我当前的代码中 我使用依赖项 log4js 在文件系统上创建日志文件 在 EC2 上 这可以创建 但在 ElasticBeanstalk 中记录某些内
  • CLion 项目中所有错误的列表

    CLion 2016 2 有助于检测您正在编辑的文件中的潜在错误 这些错误可以在代码右侧的验证栏中看到 但这只是一个文件 有没有办法 如工具窗口 来获取整个项目或其特定部分中所有此类警告的列表 如果它还列出了编译器的警告和错误 那就加分了
  • 如何在引导的 Firefox 扩展中实现 XPCOM 组件 (nsIContentPolicy)

    我有一个 Firefox 的引导扩展 现在我想实现 nsIContentPolicy XPCOM 组件 我写了一个组件模块代码 现在我想注册这个组件 我想注册组件的原因是我想将我的组件添加到nsICategoryManager addCat
  • Kubernetes 作业被创建但不会立即执行

    例如 创建如下所示的就业机会 apiVersion batch v1 kind Job metadata name test job sebas spec template spec containers name pi image per
  • OpenCV Mat 处理时间

    我想知道 OpenCV 函数的 src 源 和 dst 目标 使用不同的变量是否会对处理时间产生影响 我有下面两个函数 做同样的事情 public static Mat getY Mat m Mat mMattemp new Mat Img
  • Swift 2.0 中的 do { } catch 不会处理从这里抛出的错误

    更新 swift 2 0 后 我遇到了 do try catch 错误 如下图所示 我怎样才能解决这个问题 谢谢 该错误告诉您封闭的捕获并不详尽 这是因为自动生成的catch块只是捕获NSError对象 编译器无法判断是否有其他对象Erro
  • 变基以及变基推送提交意味着什么

    人们常说 您不应该对已经推送的提交进行变基 这可能意味着什么 To understand this we need to understand a bit about how git works A git repository is a
  • 如何使用 Jackson 和 Spring Boot 提供自定义反序列化器

    我有以下三个应用程序 项目1举行 业务逻辑 Spring Cloud Function 一个接口IDemo实体 项目2 AWS 特定的处理程序 一种实现IDemo实体 带有 DynamoDB 特定的注释 该项目基于Spring Boot 项
  • 如何在 chromedriver 中启用地理定位支持?

    我需要使用 Selenium 测试 JS 地理定位功能 并且我正在使用 chromedriver 在最新的 Chrome 上运行测试 现在的问题是 Chrome 提示我在测试期间启用地理定位 并且我不知道如何在运行时单击那个小栏 所以我拼命
  • Prolog:访问从父规则读取

    我想要一个特定的规则来读取 SWI Prolog 中的用户输入数据 例如 process do stuff read values do more stuff with X and Y here read values write Plea
  • 如何让自定义任务标签在 Eclipse 中工作?

    尝试了很多次 但我就是不知道如何在任务中定义自定义标签 我使用该对话框并创建了不同的内容 例如 TODO2 V2 或 TOVO 仅用于测试 但这些都不会扫描到任务 即使我做了类似 TODO2 或 源代码中的 V2 或 TOVO 我也尝试过重
  • 开始卡桑德拉——使用昆德拉?还有别的事吗? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我们正在接触 Cassandra 我们没有人对这个特定平台有任何经验 但都是 JavaEE JPA 等方面经验丰富的开发人员 我遇到了 Kund
  • Pivotal Cloud Foundry 登录问题

    我有一个 PWS 帐户 安装 Cloud Foundry 命令行界面 CLI 后 我尝试从 Windows 命令提示符 CYGWIN 终端和 Gitbash 登录 在上述所有情况下 我都无法登录cf login 但如果我发出命令 我就可以登
  • Grails - 将 UUID 渲染为 JSON

    我使用 UUID 作为我的域类的生成器 当我将域对象呈现为 JSON 时 id 如下所示 id class java util UUID leastSignificantBits 7570618374586820490 mostSignif
  • 在IIS中托管asp.net core应用程序,以便从网络内的其他PC访问

    如何在 Windows IIS 中托管我的 Asp Net Core 1 2 或 2 1 Web 应用程序 以便能够从本地网络 或我的虚拟操作系统 中的其他 PC 访问它 我的电脑是桌面 Windows 10 Pro 不是 Win Serv
  • C++0x 标准中对导出关键字的最佳解释是什么?

    我知道在最初的C 0x标准中有一个功能叫做export 但我找不到这个功能的描述或解释 它应该做什么 另外 哪个编译器支持它 尽管标准 C 没有这样的要求 但某些编译器要求所有函数模板都需要在使用它的每个翻译单元中可用 实际上 对于这些编译