当前位置: 首页 > wzjs >正文

优惠券怎么做自己的网站媒体公关公司

优惠券怎么做自己的网站,媒体公关公司,重庆营销网站建设公司,网站怎么搬家到快云vps里面去啊模板为什么要extern? 在 C 中,多个编译单元使用同一个模板时,是否可以不使用 extern 取决于模板的实例化方式(隐式或显式),以及你对编译时间和二进制体积的容忍度。 1. 隐式实例化:可以不用 ex…

模板为什么要extern?

在 C++ 中,多个编译单元使用同一个模板时,是否可以不使用 extern 取决于模板的实例化方式(隐式或显式),以及你对编译时间和二进制体积的容忍度。


1. 隐式实例化:可以不用 extern,但存在代价
如果多个编译单元(如 a.cppb.cpp)隐式实例化同一个模板(如 MyTemplate<int>),编译器会为每个编译单元生成一份相同的实例化代码。此时:
• 允许性:C++ 标准允许这种行为(ODR 规则,多份相同定义合法)。

• 代价:
• 编译时间增加:每个编译单元重复生成模板代码。
• 二进制体积膨胀:链接器最终合并时会保留一份代码,但中间目标文件(.o)体积可能增大。
• 潜在 ODR 风险:若不同编译单元的实例化上下文不同(如宏定义差异),可能触发未定义行为。

示例:

// a.cpp
#include "MyTemplate.h"
void foo() {MyTemplate<int> a; // 隐式实例化
}// b.cpp
#include "MyTemplate.h"
void bar() {MyTemplate<int> b; // 隐式实例化
}

• 编译后,a.ob.o 各有一份 MyTemplate<int> 代码,链接时保留一份。


2. 显式实例化:必须用 extern,否则链接错误
如果多个编译单元显式实例化同一个模板(如 template class MyTemplate<int>;),则:
• 不用 extern 的后果:每个编译单元都会生成该模板实例化的定义,导致链接时 重复定义错误。
• 必须使用 extern:在头文件中声明 extern template class MyTemplate<int>;,仅在一个编译单元显式实例化。

错误示例:

// a.cpp
template class MyTemplate<int>; // 显式实例化// b.cpp
template class MyTemplate<int>; // 显式实例化:重复定义!

• 链接时报错:multiple definition of MyTemplate<int>

正确做法:

// MyTemplate.h
extern template class MyTemplate<int>; // 声明外部实例化// MyTemplate.cpp
template class MyTemplate<int>; // 显式实例化(仅一次)

3. 性能与可维护性权衡

策略是否用 extern优点缺点
隐式实例化不需要代码简单,无需额外管理编译慢,二进制体积大
显式实例化 + extern必须用编译快,体积小,控制实例化行为需手动管理声明和实例化

4. 实际工程建议

  1. 高频使用模板(如基础容器):
    • 推荐显式实例化 + extern:显著减少编译时间和二进制体积。

    • 例如:项目中广泛使用的 Vector<int>,显式实例化并集中管理。

  2. 低频使用模板(如特殊场景的工具类):
    • 允许隐式实例化:简化代码维护,避免过度设计。

  3. 跨团队/库的模板:
    • 必须显式实例化 + extern:避免二进制冲突和不可控的实例化行为。


5. 示例:显式实例化的正确用法

// ----------------------
// MyTemplate.h
template <typename T>
class MyTemplate { /* ... */ };// 声明显式实例化由 MyTemplate.cpp 提供
extern template class MyTemplate<int>;// ----------------------
// MyTemplate.cpp
#include "MyTemplate.h"// 显式实例化实现
template class MyTemplate<int>;// ----------------------
// a.cpp
#include "MyTemplate.h"
void foo() {MyTemplate<int> a; // 使用 extern 声明,不生成代码
}// ----------------------
// b.cpp
#include "MyTemplate.h"
void bar() {MyTemplate<int> b; // 同上
}

总结
• 可以不用 extern 的情况:

所有编译单元均通过隐式实例化使用模板(接受编译时间和体积代价)。
• 必须用 extern 的情况:

需要显式实例化且跨多个编译单元共享实例化代码(否则链接错误)。

最终建议:对高频使用或公共库的模板,显式实例化 + extern 是最佳实践。

不用extern方案

在 C++ 中,如果在某个编译单元中对模板进行了显式特例化(explicit specialization),而其他编译单元未声明该特例化,则其他编译单元仍会生成通用模板的隐式实例化代码,导致重复代码。以下是详细分析:


1. 显式特例化的作用域
• 特例化的可见性:显式特例化默认仅在定义它的编译单元内有效。

• 其他编译单元的行为:若未声明该特例化,编译器会隐式实例化通用模板,生成重复代码。


2. 示例场景
假设有两个源文件 a.cppb.cpp,以及一个头文件 my_template.h

文件结构

// my_template.h
template <typename T>
class MyTemplate {
public:void foo() {}
};// a.cpp
#include "my_template.h"// 显式特例化 MyTemplate<int>
template <>
class MyTemplate<int> {
public:void foo() {} // 特例化实现
};void func_a() {MyTemplate<int> obj; // 使用特例化版本
}// b.cpp
#include "my_template.h"void func_b() {MyTemplate<int> obj; // 未声明特例化,隐式实例化通用模板
}

编译结果
a.o:包含 MyTemplate<int> 的特例化代码。

b.o:包含 MyTemplate<int> 的通用模板隐式实例化代码。

• 链接时:存在两个 MyTemplate<int> 的定义,导致 链接错误(ODR 违反)。


3. 解决方案:声明特例化
要让所有编译单元使用同一个特例化版本,需遵循以下步骤:// 显式实例化常用类型
// template class MyClassstd::string; // 关键行

(1) 在头文件中声明特例化

// my_template.h
template <typename T>
class MyTemplate { /* 通用实现 */ };// 声明显式特例化(不定义)
template <>
class MyTemplate<int>;

(2) 在源文件中定义特例化

// a.cpp
#include "my_template.h"// 定义特例化
template <>
class MyTemplate<int> { /* 特例化实现 */ };

(3) 其他编译单元直接使用

// b.cpp
#include "my_template.h"void func_b() {MyTemplate<int> obj; // 使用头文件中声明的特例化版本
}

效果:
b.cpp 看到特例化声明后,不会隐式实例化通用模板。

• 链接时仅保留 a.cpp 中的特例化代码,避免重复。


4. 特例化函数的处理
对于函数模板,需使用 extern 声明避免隐式实例化:

(1) 头文件声明

// my_template.h
template <typename T>
void foo(T) { /* 通用实现 */ }// 声明显式特例化
extern template void foo(int);

(2) 源文件定义

// a.cpp
#include "my_template.h"// 定义特例化
template <>
void foo(int) { /* 特例化实现 */ }

(3) 其他编译单元

// b.cpp
#include "my_template.h"void func_b() {foo(42); // 使用 extern 声明的特例化版本
}

5. 关键规则

  1. 特例化必须可见:所有使用特例化模板的编译单元需看到其声明。
  2. ODR 要求:同一模板的显式特例化在整个程序中只能定义一次。
  3. 隐式实例化的触发条件:当未声明特例化时,编译器默认生成通用模板代码。

总结
• 会生成重复代码:若特例化未在头文件中声明,其他编译单元将隐式实例化通用模板。

• 正确做法:

  1. 在头文件中 声明显式特例化(如 extern template class MyTemplate<int>;)。
  2. 在 单个源文件 中定义特例化。
  3. 其他编译单元通过头文件引用特例化版本。

这样可确保所有编译单元使用同一份特例化代码,避免重复定义和链接错误。

http://www.dtcms.com/wzjs/15020.html

相关文章:

  • 招聘网站如何做运营百度视频免费高清影视
  • 中山网站建设文化渠道电商网站建设开发
  • 网站开发的基础知识网站seo优化心得
  • 网站开发最新架构网站优化排名的方法
  • 番禺网站建设开发英文外链平台
  • wordpress 3.8 问题广州:推动优化防控措施落地
  • 网站改版原因郑州网站优化排名
  • 猎头建设网站营销案例100例小故事及感悟
  • 别人给公司做的网站字体侵权shopify seo
  • 有没有专门的销售公司网络推广和信息流优化一样么
  • 专业网站建设报价排名轻松seo 网站推广
  • 中山网站制作建设代写平台
  • 自己怎么制作一个公众号寰宇seo
  • 网站规划设计报告平台关键词排名优化
  • 四川企业网站建设爱站网关键词
  • 做物流的可以在那些网站找客户端大连百度关键词排名
  • 新公司做网站怎么做黑马程序员培训机构在哪
  • 政府网站做3屏适配广州今日新闻头条新闻
  • 西安网站优化维护品牌营销战略
  • wap自助建论坛网站seo排名赚挂机
  • 亿建联网站是谁做的技术培训
  • 有免费的网站建设沧州网站建设推广
  • 做外贸都用什么网站seo检查工具
  • 织梦做网站要多长时间yy直播
  • 建筑类期刊排名百度seo可能消失
  • 建企业网站要多少钱网络优化培训骗局
  • 旅游的网站怎么做的百度下载
  • 如何做网站seo诊断企业网络组建方案
  • 海洋馆网站建设灰色行业seo
  • 国外网站做freelancer十大搜索引擎地址