有没有办法访问同一类模板的不同实例的私有部分?

时间:2009-07-28 04:33:10

标签: c++ templates private public

在我继续使用模板的冒险中,我不仅仅在它所拥有的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;
}

2 个答案:

答案 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;
}