Can someone please explain to me why the following won't compile?, and hopefully the obvious thing that I have missed...
functions.hpp:
template<typename T> string vector_tostr(std::vector<T> v);
functions.cpp:
template<typename T> string vector_tostr(std::vector<T> v){
std::stringstream ss;
std::string thestring = "";
if(v.size() > 0){
ss << "[";
for(size_t i = 0; i < v.size(); i++){
if(i != 0)
ss << " ";
ss << v[i];
}
ss << "]";
thestring = ss.str();
}
return thestring;
}
main.cpp
#include "functions.hpp"
int main(int argc, char *argv[]){
vector<int> thevector;
thevector.push_back(1);
thevector.push_back(2);
string result = vector_tostr(thevector);
//I have also tried vector_tostr<int>(thevector)
}
The cryptic error I am getting as follows:
Undefined symbols for architecture x86_64: "std::basic_string, std::allocator > vector_tostr(std::vector >)", referenced from: _main in main.o ld: symbol(s) not found for architecture x86_64 collect2: error: ld returned 1 exit status make: * [main] Error 1
You are not allowed to seperate the declaration and definition of a templated function in the same way that you would a normal function (declaration in '.hpp' file, definition in '.cpp' file). There are a couple of ways you can get around that.
You can declare AND define the function in the same place in the header file.
OR
You could try this, in a file called functions.inl
:
template<typename T>
inline string vector_tostr(std::vector<T> v){
std::stringstream ss;
std::string thestring = "";
if(v.size() > 0){
ss << "[";
for(size_t i = 0; i < v.size(); i++){
if(i != 0)
ss << " ";
ss << v[i];
}
ss << "]";
thestring = ss.str();
}
return thestring;
}
Then, at the end of the header file (functions.hpp
), type this in:
#include "functions.inl"
.inl
is the file extension for the inline header file. You can use this to seperate the declaration
and definition of templated functions.
Templates are instantiated in compile time. What the compiler does is create one overloaded method for each template argument value that is used in the code. For example, using int
and double
as template argument will create two overloaded methods from the same definition, only vary in argument type. So compiler must be able to see the definition while compiling. You can do this in several ways
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With