有很多在线文档解释了如何编写模板方法,但没有太多关于如何调用它们的示例,如何在代码中使用它们。
我有一个这样的模板方法:
的 VectorConvertor.h
template <class T>
static void AppendToVector(std::vector<T> & VectorToBeAppended,
std::vector<T> & VectorToAppend);
的 VectorConvertor.cpp
template <class T>
void VectorConvertor::AppendToVector(std::vector<T> & VectorToBeAppended,
std::vector<T> & VectorToAppend)
{
for (std::vector::size_type i=0; i<VectorToAppend.size(); i++)
{
VectorToBeAppended.push_back(VectorToAppend.at(i));
}
}
代码中的使用尝试
std::vector<uint8_t> InputData, OutputData;
// ...
VectorConvertor::AppendToVector(OutputData, InputData);
我编译此代码没有任何错误。但是当我尝试使用这种方法时,我得到以下错误:
错误LNK1120:1个未解析的外部
和
错误LNK2019:未解析的外部符号“public:static void __cdecl VectorConvertor :: AppendToVector(class std :: vector&gt;&amp;,class std :: vector&gt;&amp;)”(?? $ AppendToVector @ E @ VectorConvertor @@ SAXAEAV?$ vector @ EV?$ allocator @ E @ std @@@ std @@ 0 @ Z)在函数“public:staticclass std :: vector&gt; __cdecl Utf8 :: WStringToUtf8(class std :: basic_string, class std :: allocator&gt;)“(?WStringToUtf8 @ Utf8 @@ SA?AV?$ vector @ EV?$ allocator @ E @ std @@@ std @@ V?$ basic_string @ _WU?$ char_traits @ _W @ std @@ V'$分配器@ _W @ @@ 2 3 @@ Z)
当我在代码中不使用此方法时,我没有收到任何错误消息。在调用它时我做错了什么?我错过了什么吗?
我正在使用Visual Studio 2010 Express Edition。
答案 0 :(得分:7)
在C ++中,使用模板时无法在.cpp文件中分隔定义。您需要将定义放在头文件中。参见:
http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12
答案 1 :(得分:5)
您需要将函数体放在头文件中。请参阅this FAQ。
答案 2 :(得分:2)
模板链接可能会变得棘手。但最简单的解决方案通常是:
将所有模板定义放在标题文件中。
在这种情况下,您应该将VectorConverter.cpp的内容移动到VectorConverter.h(或者可能是VectorConverter.h底部的#include "VectorConverter.cpp"
)。
答案 3 :(得分:0)
除了将模板函数的定义放在标题中,或包含源文件(cpp文件)之外,您还可以为您需要的任何类型显式实例化函数。
答案 4 :(得分:0)
错误是因为尝试在CPP文件中编写模板方法的定义。为了减少链接时间,通常在头文件中编写内联和模板方法的实现(定义)。下面的代码是声明和定义模板方法的正确方法。
<强> VectorConvertor.h 强>
class VectorConvertor
{
public:
template <class T>
static void AppendToVector1( std::vector<T> & VectorToBeAppended,
const std::vector<T> & VectorToAppend);
template <class T>
static void AppendToVector2( std::vector<T> & VectorToBeAppended,
const std::vector<T> & VectorToAppend);
template <class T>
static void AppendToVector3( std::vector<T> & VectorToBeAppended,
const std::vector<T> & VectorToAppend);
}
template <class T>
void VectorConvertor::AppendToVector1( std::vector<T> & VectorToBeAppended,
const std::vector<T> & VectorToAppend)
{
VectorToBeAppended.reserve(VectorToBeAppended.size() + VectorToAppend.size());
for (std::vector<T>::size_type i=0; i<VectorToAppend.size(); i++)
{
VectorToBeAppended.push_back(VectorToAppend[i]);
}
}
template <class T>
void VectorConvertor::AppendToVector2( std::vector<T> & VectorToBeAppended,
const std::vector<T> & VectorToAppend)
{
VectorToBeAppended.reserve(VectorToBeAppended.size() + VectorToAppend.size());
for (std::vector<T>::const_iterator cit=VectorToAppend.cbegin(); cit!=VectorToAppend.cend(); ++cit)
{
VectorToBeAppended.push_back(*cit);
}
}
template <class T>
void VectorConvertor::AppendToVector3( std::vector<T> & VectorToBeAppended,
const std::vector<T> & VectorToAppend)
{
VectorToBeAppended.insert(VectorToBeAppended.end(), VectorToAppend.cbegin(), VectorToAppend.cend());
}
<强> VectorConvertor.cpp 强>
// Nothing to write in the CPP file.
而且,这是如何在代码中使用它:
std::vector<uint8_t> InputData, OutputData;
// ...
VectorConvertor::AppendToVector3(OutputData, InputData);