在我继续使用模板的冒险中,我不仅仅在它所拥有的ItemType上模板化我的Container类,而且还在一个Functor参数上模板化,该参数决定了它应该如何对项目进行排序。到目前为止,非常好。
当我想将一个Container的内容复制到另一个Container时,我遇到了一个小问题:如果两个Container有不同的Functor类型,那么它们在技术上是不相关的类。因此,容器A不允许访问容器B的非公开内容。除了制作我需要访问公共的所有内容之外,还有什么好方法可以解决这个问题吗?有可能模拟“朋友”宣言的某种方式吗?
演示问题的示例代码如下:
#include <stdio.h>
class FunctorA {};
class FunctorB {};
template <class ItemType, class Functor> class MyContainer
{
public:
MyContainer() : _metaData(0) {/* empty */}
template<class RHSFunctor> void CopyFrom(const MyContainer<ItemType, RHSFunctor> & copyFrom)
{
_metaData = copyFrom._metaData;
_item = copyFrom._item;
}
private:
int _metaData;
ItemType _item;
};
int main(int argc, char ** argv)
{
MyContainer<void *, FunctorA> containerA;
MyContainer<void *, FunctorB> containerB;
containerA.CopyFrom(containerB); // error, containerA::CopyFrom() can't access containerB's private data!
return 0;
}
答案 0 :(得分:2)
您可以在ItemType上创建基本模板类,将数据保存在那里,拥有基础的完整2-args模板子类,并将copy-from放在基类中,因为它不依赖于无论如何,仿函数。即:
template <class ItemType> class MyContainerBase
{
public:
MyContainerBase() : _metaData(0) {/* empty */}
void CopyFrom(const MyContainerBase<ItemType> & copyFrom)
{
_metaData = copyFrom._metaData;
_item = copyFrom._item;
}
protected:
int _metaData;
ItemType _item;
};
template <class ItemType, class Functor> class MyContainer:
public MyContainerBase<ItemType>
{
// whatever you need here -- I made the data above protected
// just on the assumption you may need to access it here;-)
};
答案 1 :(得分:1)
正如您所指出的,您还可以使用朋友功能:
class FunctorA {};
class FunctorB {};
template <class ItemType, class Functor> class MyContainer
{
public:
MyContainer() : _metaData(0) {/* empty */}
template<class CmnItemType, class LHSFunctor, class RHSFunctor>
friend void Copy(const MyContainer<CmnItemType, LHSFunctor> & copyFrom
, MyContainer<CmnItemType, RHSFunctor> & copyTo);
private:
int _metaData;
ItemType _item;
};
template<class CmnItemType, class LHSFunctor, class RHSFunctor>
void Copy(const MyContainer<CmnItemType, LHSFunctor> & copyFrom
, MyContainer<CmnItemType, RHSFunctor> & copyTo)
{
copyTo._metaData = copyFrom._metaData;
copyTo._item = copyFrom._item;
}
int main(int argc, char ** argv)
{
MyContainer<void *, FunctorA> containerA;
MyContainer<void *, FunctorB> containerB;
Copy(containerB, containerA);
return 0;
}