我现在坐在这上已经有一段时间了。我只是找不到答案,所以如果你们能帮忙的话会很酷。
涉及两个类,一个(XMLParser
)正在从ifstream读取并反序列化对象并将它们存储在本地可验证的中。第二个是持有vector<Someclass *> objVec;
,所以一个向量保存指向特定类型对象的指针。我把它们全部拉到一起:
ifstream file(filename, ifstream::in);
if (file.is_open())
{
XMLParser xmlParser;
file >> xmlParser;
xmlParser.fill(&objVec);
file.close();
}
XMLParser.h:
class XMLParser
{
private:
vector<Someclass> someVec;
vector<SomeOtherclass> someOtherVec;
public:
template<class T> void fill(std::vector<T*> *vec);
friend std::istream &operator>>(std::istream &stream, XMLParser &ob);
};
std::istream& operator>>(std::istream &stream, XMLParser &ob);
XMLParser.cpp:
std::istream& operator>>(std::istream &stream, XMLParser &ob)
{
//deserialize objects from stream and store them locally
return stream;
}
template <class T> void XMLParser::fill(std::vector<T*> *vec)
{
//fill the vector with the right objects
}
一切都很好,没有错误或警告。但是当它的链接时间我得到undefined reference to 'void XMLParser::fill<Someclass>(std::vector<SomeClass*, std::allocator<Someclass*> >*)'
时,XMLParser.o当然是提供的。
我尝试过的,除其他外:
包括分配器:template<class T> void fill(std::vector<T*, std::allocator<T*> > *vec)
- &gt;同样的错误
为填充宽度Someclass
编写专门化:template <> void XMLParser::fill(std::vector<Someclass*> *vec)
- &gt;工作!但不是我想要的
我在网上搜索了一些例子,但没有一个为模板提供分配器类,所以这并不是方法。 专业化正在发挥作用,但是有谁知道为什么我需要为每一个可能出现的课程提供专业化?有办法吗?因为如果我必须为可能在XML中的每个类提供特化,那么它的接缝不是非常通用的。
由于 马丁
答案 0 :(得分:0)
您需要在.cpp
文件中的头文件而不是中定义模板。该标准要求模板定义存在于声明的每个翻译单元中(如果使用)。
答案 1 :(得分:0)
有两种方法可以解决这个问题。 第一个,也是最常见的,是将模板减速放在h文件中(不仅仅是定义)。这可以通过在h中写入,或者(不太常见),包括h中的.cpp文件来完成。
另一个选项是在cpp文件中为您正在使用它的每种类型显式实例化模板。
标准状态另一种选择:在模板减速之前使用“export”,同时保持cpp文件中的定义。但是,我不知道任何实际支持它的编译器(它可能也在当前标准中被删除)。问题是,如果使用它,cpp编译之间存在依赖关系(我可以更改模板定义,而不更改h文件,并且必须重新编译使用此模板的所有cpp文件(即使h没有改变..)