class 模板的成员函数模板无法找到定义,尽管存在显式实例化。没有 link

Member function template of class template can't find definition despite explicit instantiation present. Doesn't link

编辑: 这不是 linked 问题的重复,因为我正在使用显式实例化并且只有特定类型的成员函数不 link(其他人这样做)。

以下代码编译但不编译 link,我不明白为什么。 它显式实例化 Vector class 以限制 T 的可能参数数量,因此在 .cpp 文件中隐藏了 Vector<T> 的定义。

// fwd_decl.hpp
#pragma once
template<typename T>
struct Vector; // Forward declare Vector to be used in other headers

// Vector.hpp
#pragma once
#include "fwd_decl.hpp"

template<typename T>
struct Vector
{
    template<typename U> // To allow for other types than T to be used
    Vector operator+(const Vector<U> & other) const;
    T x;
    T y;

    // more stuff..
};

// Vector.cpp
#include "Vector.hpp"
template<typename T>
template<typename U>
Vector<T> Vector<T>::operator+(const Vector<U> & other) const
{
    return { static_cast<T>(x + other.x), static_cast<T>(y + other.y) };
}
template struct Vector<int>; // Explicitly instantiate Vector<T> with int

// main.cpp
#include "Vector.hpp"
int main()
{
    Vector<int> b = Vector<int>{ 2, 3 } + Vector<int>{ 4, 5 };
}

我得到的错误是:

1>main.obj : error LNK2001: unresolved external symbol "public: struct Vector<int> __thiscall Vector<int>::operator+<int>(struct Vector<int> const &)const " (??$?HH@?$Vector@H@@QBE?AU0@ABU0@@Z)

我在 VS 15.9.4.

中使用 VC++ 17 进行编译

请注意,对 Vector<int> 成员的非函数模板调用 link 正常。

除了 Vector<T> 的显式实例之外,您还应该使用方法 template<typename T> template<typename U> Vector<T> Vector<T>::operator+(const Vector<U> & other) const 的显式实例(对于所有可能的 TU 对) class:

template Vector<int> Vector<int>::operator+(const Vector<short> & other) const;

您也可以简单地将 Vector<T>::operator+ 方法的定义移动到头文件中。

在 C++11 中引入了 extern template 指令。您可以在 Vector<T> class 的头文件中使用它(如 @StoryTeller ):

extern template struct Vector<int>;

... 以防止编译器在每个翻译单元中实例化 Vector<T> class 使用其特化。当然,相同的 extern template 指令也可用于 .cpp 文件中显式实例化的所有 Vector<T>::operator+ 特化。