尚未解决的外部使用模板类与复制和交换
-
27-10-2019 - |
题
我得到一个接头时的错误使用一个模板类在这里我试图执行的复制和交换句成语作为建议:
该模板类,让我们叫它"TemplateClass"是部分地定义这样的:
template< class T >
class TemplateClass
{
// ...
TemplateClass< T >& operator= ( TemplateClass< T > other );
friend void swap( TemplateClass< T >& first, TemplateClass< T >& second );
// ...
};
我已经把实现在一个单独的TemplateClass.cpp 其中包括在。h文件。(编辑:我有同样的问题,如果一切都在.h文件)
分配操作者的定义为:
template< class T >
TemplateClass< T >& TemplateClass< T >::operator= ( TemplateClass< T > other )
{
// copy-and-swap idiom
swap( *this, other );
return *this;
}
和交换方法是定义为:
template< class T >
void swap( TemplateClass< T >& first, TemplateClass< T >& second )
{
using namespace std;
swap( first.member1, second.member1 );
swap( first.member2, second.member2 );
// ...
}
(不要担心,我不真正名字我的成员"方的member1"等)
我有一个类似的定义是以同样的方式,但不是一个模板类。一切正常。然而,如果我有一个类 TestClass
其中有一个成员 TemplateClass< HandledClass > member
和我做呼叫其中一个方法一样
void TestClass::setMember( TemplateClass< HandledClass > newObject )
{
member = newObject;
}
我获得一个尚未解决的外在错误:
LNK2019:尚未解决的外在象征"无效__cdecl交换(类TemplateClass&,类TemplateClass&)"(...)在功能":类TemplateClass X&__thiscall TemplateClass X::员=(类TemplateClass)"(...)在TestClass.obj
或者换句话说:东西在 TestClass
电话 TemplateClass<HandledClass>::operator=
它没有找到 void swap( TemplateClass<HandledClass>, TemplateClass<HandledClass> )
.
所以我的问题是:为什么操作人员找不到的交换方法?
它看起来就像是没有编制模板的论点。是它在某种程度上可能有编译器编朋友空洞吗?
我大概可以放弃 friend void
方法和定义的一类交换方法加上一个出类拔方法加上一个在性病的名字空间,但是我不知道,如果它会工作的方式和我想避免,如果可能的话无论如何。
方案:
这样的工作:
template< class t >
class TemplateClass
{
friend void swap( TemplateClass& first, TemplateClass& second )
{
// ...
}
};
注意如何我都删除 < T>次出现。
解决方案
这是一个常见的问题时认识的非成员的功能的模板。的 friend
宣言的内部 TemplateClass
不亲近你 swap
模板,而非模板功能 swap
这需要 TemplateClass<T>
对曾经 T
该模板的实例(即专业化 TemplateClass<int>
将协助免费的功能 void swap( TemplateClass<int>&,TemplateClass<int>& );
这不是模板).
最好的解决办法是提供 swap
定义内联内流模板的定义,因为这将使编译器产生的非模板 swap
功能用于准确的类型,每当需要。作为另一个积极的副作用, swap
功能只会发现在参数的依赖查找,所以它不会把一部分载的决议对于任何不涉及到你的模板。
其他方案是整个交朋友 swap
模板功能,或者认识的特别是专业化的 swap
功能时施加相同的 T
这一模板已经实例。第一个选项是简单的代码,但是它授权访问 所有 该专业的 swap
模板,并可能有不良的副作用。交朋友的特别 swap
专业化,解决了这一问题,但是多一点的复杂的实施(你需要向前声明这类模板,然后 swap
模板,然后定义类模板,并最后定义 swap
模板)。
更多关于这个在这其他 答案, ,其中不同的选择和语法解释的更详细的说明。
作为特定的错误消息的 unresolved external
, ,这是由于如何标识查询工作。当你使用 swap(*this,other);
内部成员的功能,开始查找在内部流,并试图找到一个合适的 swap
.它第一次看起来在类方面,并认为《宣言》的 friend
免费的功能,因此查找并未继续向外增加了一个依赖,尤其是免费的功能。它增加的依赖性和等待接头找到适当的符号。因为编译器从来没有考虑的模板 swap
在名字空间的水平,它从来没有真正实例,但即使它有化,模板,依赖内部 operator=
部件的功能是免费的功能的,不是专业化。
其他提示
您应该将类模板的声明放入头文件中,或者如果您事先知道将使用该类模板实例化的所有类型,请在头文件中提供显式实例化: 通用标签
这很乏味,但有时是最好的选择。
关于交换为什么不链接的原因:使用不存在的非模板函数交换来声明Friendnes。尝试以下操作: 通用标签
如果您想成为一个纯粹主义者并且仅与“您的” swap
(具有相同模板参数的swap
)成为朋友,则需要付出额外的努力。