为什么模板专用化需要内联定义?

Why does a template specialization require an inline definition?

本文关键字:定义 专用 为什么      更新时间:2023-10-16

在§14.4.1"加速C++,A. Koenig 和 B. E. Moo"中给出的例子中,如果我像书中介绍的那样实现模板专业化,我会遇到问题。

最小工作示例(自上而下(为:

g++ str.cpp main.cpp

主.cpp:

#include "str.hpp"
int main(int argc, char** argv)
{
Str n;                //def
return 0;
}

str.hpp:

#ifndef GUARD_str_h
#define GUARD_str_h
#include <vector> 
#include "ptr.hpp"
class Str {
public:
Str(): data(new std::vector<char>) { }
private:
Ptr< std::vector<char> > data;
};
#endif

str.cpp:

#include "str.hpp"

PTR.hpp:

#ifndef GUARD_ptr_h
#define GUARD_ptr_h
#include <vector> 
template<class T> T* clone(const T* tp);
template<> std::vector<char>* clone(const 
std::vector<char>* vp);
template <class T> class Ptr {
public:
Ptr(): refptr(new size_t(1)), p(0) { }
Ptr(T* t): refptr(new size_t(1)), p(t) { }
~Ptr();
private:
T* p;
size_t* refptr;
};
#include "ptr.cpp"
#endif

PTR.cpp:

template<class T>
Ptr<T>::~Ptr()
{
if (--*refptr == 0) {
delete refptr;
delete p;
}
}
template<class T>
T* clone(const T* tp)
{
return tp->clone();
}
template<>
std::vector<char>* clone(const std::vector<char>* vp)
{
return new std::vector<char>(*vp);
}

问题是最后一个模板专用化

template<> std::vector<char>*

它给出了一个

multiple definition of 'std::vector<char...>

错误。它仅适用于

template<> inline std::vector<char>*

1(我不完全明白为什么我需要"内联"。

2(这是书中的错误吗?我试图将此模板专用化放在 ptr.hpp 文件中。同样,它仅适用于"内联"。

感谢所有能够阐明这个问题的人。

模板是在编译时生成的。所以如果你有这个:

template <class T> void func(T t) { /*...*/ }

这个 - 如果你使用它,像这样:

func<int>(5);

编译器将生成此函数:

void func(int t) { /*...*/ }

如果模板类方法定义位于单独的源文件中,则可以将其与主文件分开编译。编译器将无法确定要生成哪些函数。如果它是inline,它基本上是一个宏,不能导出到另一个模块。