Reputation: 10911
There are a lot of online documents explaining how to write template methods, but not much example about how to call them, how to use them in code.
I have a template method like this:
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));
}
}
Usage attempt in code:
std::vector<uint8_t> InputData, OutputData;
// ...
VectorConvertor::AppendToVector(OutputData, InputData);
I compile this code without any error. But when I try to use this method I get the following errors:
error LNK1120: 1 unresolved externals
and
error LNK2019: unresolved external symbol "public: static void __cdecl VectorConvertor::AppendToVector(class std::vector > &,class std::vector > &)" (??$AppendToVector@E@VectorConvertor@@SAXAEAV?$vector@EV?$allocator@E@std@@@std@@0@Z) referenced in function "public: staticclass std::vector > __cdecl Utf8::WStringToUtf8(class std::basic_string,class std::allocator >)" (?WStringToUtf8@Utf8@@SA?AV?$vector@EV?$allocator@E@std@@@std@@V?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@3@@Z)
When I don't use this method in my code I don't get any error messages. What am I doing wrong while calling it? Am I missing something?
I'm using Visual Studio 2010 Express Edition.
Upvotes: 6
Views: 5964
Reputation: 10911
The errors are because of trying to write the definition of the template method in the CPP file. In order to reduce the linking time, it is a rule to write the implementation (definition) of the inline and template methods in the header file. The code below is the correct way of declaring and defining a template method.
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.
And, this is how to use it in the code:
std::vector<uint8_t> InputData, OutputData;
// ...
VectorConvertor::AppendToVector3(OutputData, InputData);
Upvotes: 0
Reputation: 64223
Besides placing the definition of the template function in the header, or including the source file (cpp file), you could explicitly instantiate your function for whichever types you need it.
Upvotes: 0
Reputation: 72271
Template linking can get tricky. But the simplest solution is usually:
Put all template definitions in header files.
In this case, you should move the contents of VectorConverter.cpp to VectorConverter.h (or possibly #include "VectorConverter.cpp"
at the bottom of VectorConverter.h).
Upvotes: 2
Reputation: 5388
In C++ you can't separate the definition in a .cpp file when using templates. You need to put the definition in the header file. See:
http://www.parashift.com/c++-faq-lite/templates.html#faq-35.12
Upvotes: 7