Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从单独文件转发模板函数声明_C++_Templates_Forward Declaration - Fatal编程技术网

C++ 从单独文件转发模板函数声明

C++ 从单独文件转发模板函数声明,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{ ";

其他.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;
}
#包括
#包括
使用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);
}