首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >为什么模板只能在头文件内定义

为什么模板只能在头文件内定义

作者头像
ClearSeve
发布2022-02-10 19:09:16
发布2022-02-10 19:09:16
1.6K00
代码可运行
举报
文章被收录于专栏:ClearSeveClearSeve
运行总次数:0
代码可运行

问题

The C++ standard library: a tutorial and handbook 中有一句话,

The only portable way of using templates at the moment is to implement them in header files by using inline functions.(目前使用模板的唯一方法就是在头文件中实现为内联。)

为什么只能实现在头文件呢?

回答

首先,模板也是可以不必实现在头文件中的。

我们知道 C++ 中每一个对象所占用的空间大小,是在编译的时候就确定的,在模板类没有真正的被使用之前,编译器是无法知道,模板类中使用模板类型的对象所占用的空间的大小。只有模板被真正使用的时候,编译器才知道,模板套用的是什么类型,应该分配多少空间。这也就是模板类为什么只是称之为模板,而不是泛型的缘故。

既然是在编译的时候,根据套用不同类型来进行编译,那么,套用不同类型的模板类实际上就是两个不同的类型,也就是说,stack<int>stack<char> 是两个不同的数据类型,他们共同的成员函数也不是同一个函数,只不过具有相似的功能罢了。

举个例子:

代码语言:javascript
代码运行次数:0
运行
复制
template<typename T>
struct Foo
{
    T bar;

    void doSomething(T param)
    {
        ....
    }
};

// 在另一个 .cpp 文件中定义如下变量
Foo<int> f; 

编译器需要做的就是根据这个模板创建一个新的类(姑且叫做 FooInt),其实就等价于:

代码语言:javascript
代码运行次数:0
运行
复制
struct FooInt
{
    int bar;
    void doSomething(int param)
    {
        ....
    }
}

当编译器需要找到方法实现,并用模板参数去实例化它们的时候,比如这个情况下是 int。如果实现不在头文件,那么方法就访问不到,自然而然编译器就不能实例化那个模板。

一个常用的方法是,在头文件中声明模板,在一个模板文件中实现具体的定义,然后在头文件的尾部包含具体实现的文件。例如:

代码语言:javascript
代码运行次数:0
运行
复制
// Foo.h
template <typename T>
struct Foo
{
    void doSomething(T param);
};

#include "Foo.tpp"
代码语言:javascript
代码运行次数:0
运行
复制
// Foo.tpp
template <typename T>
void Foo<T>::doSomething(T param)
{
    //implementation
}

上面的做法不够好,只是看起来是分离开了。我们可以使用下面的方法:

代码语言:javascript
代码运行次数:0
运行
复制
// Foo.h

// no implementation
template <typename T> struct Foo { ... };
代码语言:javascript
代码运行次数:0
运行
复制
// Foo.cpp

// implementation of Foo's methods

// 显示实例化,但是缺点就是,你只能使用这两个实例了,其它的都不能用
template class Foo<int>;
template class Foo<float>;

C++ Super-FAQ 也有对此说明,可以参考这里: https://isocpp.org/wiki/faq/templates#templates-defn-vs-decl

参考

  • https://www.zhihu.com/question/20630104/answer/15722407
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年1月24日,如有侵权请联系 [email protected] 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 [email protected] 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题
  • 回答
  • 参考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档