C++ 从单独文件转发模板函数声明
其他.cppC++ 从单独文件转发模板函数声明,c++,templates,forward-declaration,C++,Templates,Forward Declaration,其他.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{ ";
#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;
}
#包括
#包括
使用std::cout;
模板
std::ostream&cprint(T&T,std::string msg=“Container”,std::ostream&stream=cout){
流除此之外,您还应该阅读:
若要使用extern
延迟实例化,必须精确匹配函数签名,因此除非T
定义为std::vector
或其别名(与模板声明匹配),否则下面将不起作用:
extern template std::ostream & cprint<std::vector<int>>
(T &t, std::string msg = "Container", std::ostream & stream = cout);
extern模板std::ostream&cprint
(T&T,std::string msg=“Container”,std::ostream&stream=cout);
要解决
extern template std::ostream& cprint<std::vector<int>>
(std::vector<int>&, std::string msg = "Container", std::ostream & stream = cout);
extern模板std::ostream&cprint
(std::vector&,std::string msg=“Container”,std::ostream&stream=cout);
看到了吗
更具体地说,
在Header.hpp文件中,我有它的声明和延迟:
模板
std::ostream&cprint(T&T,std::string msg=“Container”,std::ostream&stream=cout){
请记住,您所问的(通常)不是使用模板的正确方法。
您应该做的是在头中声明模板,并摆脱extern
声明和显式专门化。
将模板放入.cpp
s通常不是很方便,因为它们要求您在同一.cpp
中指定希望它们使用的所有类型
但是,另一方面,它提高了编译速度,并且生成的二进制文件较小的可能性很小
如何修复代码:
我对您的代码做了一些更改以使其正常工作
我也做了一些小的改进。如果你觉得让人困惑,可以在评论中询问
// 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);
}
//1.cpp
#包括
#包括
#包括
模板
std::ostream&cprint(const T&T,std::string msg=“Container”,std::ostream&stream=std::cout)
{
stream您得到了什么错误?您不仅做得不对,而且整个想法都是错误的,请阅读这里@Slava好吧,如果您手动指定模板必须工作的所有类型,则可以将模板放入单独的文件中。@HolyBlackCat'cprint'不是模板函数
和预期';'before'@HolyBlackCat现在是,但看起来是从OP的问题到理解水平,这不是他试图做的。我打赌下一个OP的问题-为什么它不起作用。你确定你回答了OP的问题吗?@WhiZTiM我编辑了这个问题以简化解决方案。即使我显式编写所有类型,编译器仍然会给出错误。@WhiZTiM'cprint'不是模板函数n
错误根据您的代码您是对的。我完全是以错误的方式做的。我应该使用标题并在标题中定义所有内容。答案解决了问题,但我不同意模板定义只属于标题,或者它们的主要目的是减少编译时间或二进制大小;事实上,它们可以做到这一点e相反,特别是如果它们是在标题中定义的。@gcbenison指出,编辑了答案。我同意,有时将模板放入.cpp
中可能会有用。关于更快的编译速度和较小的二进制大小的部分是关于位于.cpp
s中的模板,而不是标题。我更改了措辞以使其更清楚。
extern template std::ostream& cprint<std::vector<int>>
(std::vector<int>&, std::string msg = "Container", std::ostream & stream = 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;
}
//defer instantiation
extern template std::ostream& cprint<std::vector<int>>
(std::vector<int>&, std::string msg = "Container", std::ostream & stream = cout);
int main(){
std::vector<int> v{1, 2, 3, 4, 5};
cprint(v);
}
template std::ostream& cprint<std::vector<int>>
(std::vector<int>&, std::string msg = "Container", std::ostream & stream = cout);
template <typename T>
void func(T x){
cout << x << endl;
}
// 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);
}