尽管存在显式实例化,但类模板的成员函数模板找不到定义。不连结 [英] Member function template of class template can't find definition despite explicit instantiation present. Doesn't link

查看:209
本文介绍了尽管存在显式实例化,但类模板的成员函数模板找不到定义。不连结的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆