other.cpp
#include <iostream>
#include <string>
using std::cout;
template <typename T>
std::ostream & cprint(T &t, std::string msg = "Container", std::ostream & stream = cout){
stream << msg << "\t{ ";
for(typename T::iterator it = t.begin(); it != t.end(); it++)
stream << *it << " ";
stream << "}\n";
return stream;
}
I have a template function in a separate file. and i am trying to forward declare it in main.cpp file.
extern template std::ostream & cprint<std::vector<int>>
(T &t, std::string msg = "Container", std::ostream & stream = cout);
I have tried something as above but it didn't work for me.
Edit: assume other.cpp has a basic function as below,
template <typename T>
void func(T x){
cout << x << endl;
}
how to instantiate this function in main.cpp?
What you should do is to declare your template in a header and get rid of the extern
declarations and explicit specializations.
Putting templates into .cpp
s usually isn't very convenient because they require you to specify all types you want them to work for in the same .cpp
.
But, on the other hand, it improves compilation speed and there is a small chance that the resulting binary will be smaller.
I made some changes to your code to make it work.
I also made some minor improvements. Ask in comments if you find them confusing.
// 1.cpp
#include <iostream>
#include <string>
#include <vector>
template <typename T>
std::ostream &cprint(const T &t, std::string msg = "Container", std::ostream &stream = std::cout)
{
stream << msg << " { ";
for(typename T::const_iterator it = t.cbegin(); it != t.cend(); it++)
stream << *it << " ";
stream << "}\n";
return stream;
}
template std::ostream &cprint(const std::vector<int> &, std::string, std::ostream &);
// 2.cpp
#include <string>
#include <iostream>
#include <vector>
template <typename T> std::ostream &cprint(const T &, std::string = "Container", std::ostream & = std::cout);
int main()
{
std::vector<int> v{1,2,3};
cprint(v);
}
Important parts are following:
Explicit instantination. It must be located in a same file as a template definion.
template std::ostream &cprint(const std::vector<int> &, std::string, std::ostream &);
Declaration. It must be in a file where you want to use your template.
template <typename T> std::ostream &cprint(const T &, std::string = "Container", std::ostream & = std::cout);
Note that you can manually specify template arguments in explicit instantination and extern declaration if compiler can't deduce them.
Doing the same thing with a dummy template which was edited into a question is left as an excercise to the reader.