为啥模板特化需要内联定义? [复制]

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++模板详解:泛型编程模板原理非类型模板参数模板特化分离编译

C++模板编程中只特化模板类的一个成员函数(花样特化一个成员函数)

C++模板——完全特化

函数模板参数包后跟模板参数和特化

6.4-数据结构&算法-模板/函数模板/类模板/特化