C++ 如何在函数模板中使用前向声明的datamembers?(C+;+;)
所以我有一个类,在其中我使用前向声明类的datamembers。现在我需要我的类的函数模板,但函数模板需要在头文件中实现,所以我不能访问我的成员。我怎样才能解决这个问题 这是我的一些代码C++ 如何在函数模板中使用前向声明的datamembers?(C+;+;),c++,templates,C++,Templates,所以我有一个类,在其中我使用前向声明类的datamembers。现在我需要我的类的函数模板,但函数模板需要在头文件中实现,所以我不能访问我的成员。我怎样才能解决这个问题 这是我的一些代码 class Cell; class Node; class Wall : public WallAttributes { public: /// virtual ~Wall() {} private: Cell* m_c1; /
class Cell;
class Node;
class Wall : public WallAttributes
{
public:
///
virtual ~Wall() {}
private:
Cell* m_c1; ///<
Cell* m_c2; ///<
Node* m_n1; ///<
Node* m_n2; ///<
unsigned int m_wall_index; ///<
private:
mutable double m_length; ///< Length is tracked lazily.
mutable bool m_length_dirty; ///< Marks length dirty.
private:
friend class cereal::access;
template<class Archive>
void save(Archive & archive) const
{
archive(m_c1->GetIndex());
archive(m_c2->GetIndex());
archive(m_n1->GetIndex());
archive(m_n2->GetIndex());
archive(m_wall_index);
archive(m_length);
archive(m_length_dirty);
}
template<class Archive>
void load(Archive & archive)
{
//Todo
}
};
类单元;
类节点;
类墙:公共wallettributes
{
公众:
///
虚拟~Wall(){}
私人:
单元*m_c1///<
单元*m_c2///<
节点*m_n1///<
节点*m_n2///<
无符号整数m_wall_索引///<
私人:
可变双m_长度;//<长度被延迟跟踪。
可变布尔m_length_dirty;//<标记长度dirty。
私人:
好友类:访问;
模板
无效保存(存档和存档)常量
{
存档(m_c1->GetIndex());
存档(m_c2->GetIndex());
存档(m_n1->GetIndex());
存档(m_n2->GetIndex());
档案(m_wall_索引);
档案(单位长度);
存档(m_长度_脏);
}
模板
无效加载(存档和存档)
{
//待办事项
}
};
这会导致错误:不完整类型单元格的使用无效请尝试以下方法:
class Wall : public WallAttributes {
// ...
private:
template<class Archive>
void load(Archive& archive);
};
// ...
#include "wall.tpp" // templates definitions
然后,您可以在包含“wall.tpp”之前或在该文件中包含单元格的标题
或者,您也可以使用此方法:
wall.tpp
:
template<class Archive>
void Wall::load(Archive& archive) {
// ..
}
template<>
void Wall::load<Cell>(Cell& archive); // declare template specialization for Cell type
可以将模板定义移动到源文件(Wall.cpp)
将标题更改为:
class Wall : public WallAttributes{
private:
template<class Archive>
void save(Archive & archive) const;
template<class Archive>
void load(Archive & archive);
}
类墙:公共Wallet属性{
私人:
模板
作废保存(存档和存档)常数;
模板
无效加载(归档和归档);
}
在Wall.cpp上:
template<class Archive>
void save(Archive & archive) const
{
(...)
}
template<class Archive>
void load(Archive & archive)
{
(...)
}
模板
无效保存(存档和存档)常量
{
(...)
}
模板
无效加载(存档和存档)
{
(...)
}
因为模板函数是私有的,所以我假设它们只在Wall.cpp中使用。但如果不是这样,您可以使用模板定义创建一个中间cpp文件,如Wall-templates.cpp,并将该cpp文件包含在您的Wall.cpp中。为什么不能完整定义单元格和节点
?创建一个具有纯虚拟函数的基本归档类来执行任何操作。使用一些包装类和指针或实际归档类的实例从归档类型继承,并在运行时传递。现在您可以创建一个非模板函数,该函数引用您的存档基类。@jrok以避免标头膨胀?这是一个很好的技巧。由于您使用的成员包括单元格
和节点
,因此您需要这些类的完整定义,否则编译器将不知道它们有哪些成员。这不是我的代码,我的任务是使项目可序列化,这样我就不能更改代码的结构。这如何解决定义不完整的问题?对,我已经解决了这个问题。它们是私有的,但在它们上面有一个friend
声明。我怀疑这就是它们应该被调用的地方。好吧,这就是为什么我添加了在“Wall templates.cpp”中放置定义的可能性
template<class Archive>
void save(Archive & archive) const
{
(...)
}
template<class Archive>
void load(Archive & archive)
{
(...)
}