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
的显式实例(对于所有可能的 T
和 U
对) 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+
特化。
编辑: 这不是 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
的显式实例(对于所有可能的 T
和 U
对) 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+
特化。