函数模板显式实例化extern

时间:2014-02-03 11:21:03

标签: c++ templates instantiation extern

我有一个函数,它对许多基本类型都有完全相同的代码。为了保存代码行,我想声明它作为模板,并为所有后来使用的类型显式实例化它一次:头文件中的声明和cpp文件中的实现+显式实例化(与写正常功能围兜相同的设计。)

我的方法是:

// header.h
template <class T> T func (T arg);


// header.cpp
#include "header.h"

template <class T> T func (T arg)
{
    // implementation...
}
template int func<int> (int arg);
template double func<double> (double arg);

然而,在parashift,我找到了这种形式的声明:

// header.h
template <typename T> extern void foo();

这里的外在感是什么?它与我的方法有何不同?什么是正确的?

也不必将正常函数声明为extern。如果它是extern template void foo<int>();(参见接受的答案here)会有所不同,禁止编译器实例化已经实现的模板在头文件中。

修改

// header.h
int func (int arg);
double func (double arg);

// header.cpp
#include "header.h"

int func (int arg)
{ ... }
double func (double arg)
{ ... }

不完全类似/等同于

// header.h
template <class T> T func (T arg);
// here is the question: like above or template <class T> extern T func (T arg); ???

// header.cpp
#include "header.h"

template <class T> T func (T arg)
{ ... }
template int func<int> (int arg);
template double func<double> (double arg);

关于以后的用法

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

int main ()
{
    // for overloading
    func(20);
    func(20.0);
    func((int)20.0);

    // for template
    func(20); // == func<int>(20)
    func(20.0); // == func<double>(20.0)
    func((int)20.0); // == func<int>((int)20.0)
    func<int>(20.0); // == func<int>((int)20.0)

    return 0;
}

1 个答案:

答案 0 :(得分:0)

你的语法在头文件中声明存在某个地方template <class T> T func (T arg);仍然不允许用户使用该模板函数获取代码,但是让模板代码执行该操作(哪个编译器不会能够在没有看到模板函数定义的情况下实例化。)

您所引用的FAQ部分的特点是语法声明某个类X的某个类和编译器存在模板实例化,当看到X x = func(X());不应该实例化模板而是离开时符号未解析,让链接器处理它。