c++ - 为什么模板特化需要内联定义?

标签 c++ templates inline specialization multiple-definition-error

这个问题在这里已经有了答案:





When should I write the keyword 'inline' for a function/method?

(16 个答案)



Does it make any sense to use inline keyword with templates?

(4 个回答)


2年前关闭。




在 §14.4.1 “Accelerated C++, A. Koenig and 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 ,它基本上是一个宏,不能导出到另一个模块。

关于c++ - 为什么模板特化需要内联定义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59529878/

相关文章:

c++ - cin 和 switch 奇怪的行为

c++ - Stanley Lipmann 的 "C++ Primer"中的库类型

c++ - 嵌套模板参数

scala - 如何确保内联类型匹配(scala 3)中的两个参数引用相同的类型

c++ - 同一函数的两个版本(用于内联或 constexpr)

c++ - 子数组中两个数字的相同出现(连续)

c++ - 如何访问脚本中定义的类型的成员?

ruby-on-rails - 如何在 Ruby on Rails 中实现特定于部分的导航?

c++ - 如何正确声明以函数类型为参数的模板(如 std::function)

c# - 为什么默认情况下不内联自动属性?