为啥模板特化需要内联定义? [复制]
Posted
技术标签:
【中文标题】为啥模板特化需要内联定义? [复制]【英文标题】:Why does a template specialization require an inline definition? [duplicate]为什么模板特化需要内联定义? [复制] 【发布时间】:2019-12-30 11:13:31 【问题描述】:在第 14.4.1 节“加速 C++,A. Koenig 和 B. E. Moo”中给出的示例中,如果我像书中介绍的那样实现模板专业化,我会遇到问题。
最小的工作示例(自上而下)是:
g++ str.cpp main.cpp
main.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 文件中。同样,它只适用于“内联”。
感谢所有能够阐明这个问题的人。
【问题讨论】:
@bolov,似乎是一个错误的副本。这个问题是关于完全专业化的,实际上不必在标题中实现。在我看来,此示例中的主要问题是 *.cpp 文件包含在标头中。 这似乎是一个更好的欺骗目标When should I write the keyword 'inline' for a function/method? 还有Does it make any sense to use inline keyword with templates?。 【参考方案1】:模板是在编译时生成的。所以如果你有这个:
template <class T> void func(T t) /*...*/
这个 - 如果你像这样使用它:
func<int>(5);
编译器会生成这个函数:
void func(int t) /*...*/
如果您在单独的源文件中有模板类方法定义,则它可能与主文件分开编译。编译器将无法确定要生成哪些函数。如果是inline
,基本上就是一个宏,不能导出到别的模块。
【讨论】:
以上是关于为啥模板特化需要内联定义? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
C++模板详解:泛型编程模板原理非类型模板参数模板特化分离编译
C++模板详解:泛型编程模板原理非类型模板参数模板特化分离编译