尽管存在显式实例化,但类模板的成员函数模板找不到定义。不连结 [英] Member function template of class template can't find definition despite explicit instantiation present. Doesn't link
问题描述
编辑:这不是链接问题的重复,因为我使用的是显式实例化,只有特定类型的成员函数不链接(其他人则链接)。
This is not a duplicate of the linked question since I am using explicit instantiation and only a specific type of member functions do not link (others do).
以下代码可以编译,但是没有链接,我也不明白为什么。
它显式实例化 Vector
类以限制 T
的可能参数的数量,因此隐藏了.cpp文件中 Vector< T>
的定义。
The following code compiles but doesn't link and I don't understand why.
It is explicitly instantiating the Vector
class to limit the number of possible arguments for T
and therefore hides the definition of Vector<T>
in a .cpp file.
// 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 进行编译。
I'm compiling with VC++ 17 in VS 15.9.4.
请注意,对不是函数模板的 Vector< int>
成员的调用会正常链接。
Note that calls to members of Vector<int>
that are not function templates do link normally.
推荐答案
您应使用方法 template< typename T>的显式实例化。 template< typename U>向量T Vector< T> :: operator +(const Vector< U& other)const
(对于 T
和<$ c $的所有可能对c> U )以及 Vector< T>
类的显式实例:
You should use the explicit instantion of the method template<typename T> template<typename U> Vector<T> Vector<T>::operator+(const Vector<U> & other) const
(for all possible pairs of T
and U
) in addition to the explicit instantion of the Vector<T>
class:
template Vector<int> Vector<int>::operator+(const Vector<short> & other) const;
也可以简单地移动 Vector< T>的定义:
Also you may simply move the definition of the Vector<T>::operator+
method to the header file.
在C ++ 11中,外部模板
指令被引入。您可以在 Vector< T>
类的头文件中使用它(如 @StoryTeller 建议在注释中):
In C++11 the extern template
directive was introduced. You may use it in the header file for Vector<T>
class (as @StoryTeller suggested in the comments):
extern template struct Vector<int>;
...以防止编译器实例化 Vector< T>
类在每个翻译单元中都使用其专业知识。当然,相同的 extern模板
指令也可以用于所有 Vector< T> :: operator +
专门实例化的实例。 .cpp
文件。
...to prevent the compiler from instantiating the Vector<T>
class in every translation unit its specializations are used. Of course the same extern template
directives may also be used for all Vector<T>::operator+
specializations explicitly instantiated in the .cpp
file.
这篇关于尽管存在显式实例化,但类模板的成员函数模板找不到定义。不连结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!