c++ - 尽管存在显式实例化,但类模板的成员函数模板找不到定义。不链接

标签 c++ templates visual-c++ c++17 explicit-instantiation

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

以下代码编译但不链接,我不明白为什么。 它显式实例化了 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> 的成员不是函数模板的链接可以正常链接。

最佳答案

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

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

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

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

extern template struct Vector<int>;

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

关于c++ - 尽管存在显式实例化,但类模板的成员函数模板找不到定义。不链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54081512/

相关文章:

c++ - 从主应用程序中取消停靠子窗口

c++ - std::move 是否使指针无效?

c++ - 派生类中的显式模板静态成员实例化

c++ - 以大字体打印 "HELLO"?

c++ - 为什么无法创建堆栈大小小于默认大小的线程?

c++ - 函数名称修改。 _cdecl约定

c++ - 是什么导致 WriteFile 返回 ERROR_ACCESS_DENIED?

c++ - PostThreadMessage 到另一个进程

c++ - 动态创建数组 - 无法推断 'T' 的模板参数 - C++

c++ - 在模板参数包上使用类型特征?