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

做设计素材在哪个网站seo和sem的区别是什么

做设计素材在哪个网站,seo和sem的区别是什么,日照网站建设,网页设计个人总结800模板为什么要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/479539.html

相关文章:

  • 网络广告营销方案策划内容兰州网站seo
  • 制作一个网站需要多久seo网站优化经理
  • 万网网站备案多久外链相册
  • 做rom的网站淄博网站制作
  • 卧龙区2015网站建设口碑网站外链出售
  • 网站制作常见的问题网络营销方案的制定
  • 做网站兼容ie五合一网站建设
  • 嘉兴网站推广优化费用企业网站推广方法
  • 集约化网站建设的函广州疫情最新动态
  • wordpress 分类目录 404seo搜索优化费用
  • 网站开发协议书由谁来写品牌推广专员
  • 简述网站建设的基本思路上海网站建设
  • 网站建设过程小结广东广州疫情最新情况
  • 深圳网站建设 百业免费网站统计
  • 铜仁市住房和城乡建设局网站福建seo推广方案
  • 网站搭建的seo收费
  • 网站维护主要内容网络营销是什么课程
  • 表格 wordpress优化培训学校
  • 河南海华工程建设监理公司网站网络推广常见的方法
  • 响应式网站开发软件seo营销方案
  • 按摩养生网站建设郑州做网站公司有哪些
  • 免费学做美食视频网站有哪些网站播放视频速度优化
  • 钦州网站建设哪家便宜上海百度推广电话客服
  • 云虚拟机可以做几个网站网站seo基础
  • 什么网站可以做ppt模板seo公司怎么推广宣传
  • 网上商城网站设计福建百度开户
  • 住房建设部官方网站居住区政策百度收录时间
  • 基于cms系统网站的建设91
  • wordpress 捐赠廊坊seo网络推广
  • 中山网站设计外包百度推广哪种效果好