使用模板类时出现链接器错误,我尝试按照此处的建议实现复制和交换习惯用法:
模板类,我们称之为“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:函数“public: class TemplateClass X & __thiscall TemplateClass X::operator=(class TemplateClass)”(...) 中未解析的外部符号“void __cdecl swap(class TemplateClass &, class TemplateClass &)”(...)在 TestClass.obj 中
或者换句话说:TestClass
调用TemplateClass<HandledClass>::operator=
中找不到的东西void swap( TemplateClass<HandledClass>, TemplateClass<HandledClass> )
。
所以我的问题是:为什么运营商找不到swap方法?
看起来它不是为模板参数编译的。是否有可能让编译器也编译友元 voids?
我可能会放弃这种friend void
方法并定义一个类内交换方法加上一个类外交换方法加上一个 std 命名空间中的一个,但我不知道它是否会这样工作,如果我想避免这种情况反正可能。
解决方案:
这完成了工作:
template< class t >
class TemplateClass
{
friend void swap( TemplateClass& first, TemplateClass& second )
{
// ...
}
};
请注意我也必须删除 < T > 事件。