1

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

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

// 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>不是函数模板的成员的调用确实可以正常链接。

4

1 回答 1

2

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

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

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

在 C++11extern template中引入了该指令。您可以在类的头文件中使用它Vector<T>(正如@StoryTeller 在评论中建议的那样):

extern template struct Vector<int>;

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

于 2019-01-08T11:17:00.900 回答