3

テンプレートを使った継続的な冒険では、Containerクラスを、それが保持するItemTypeだけでなく、アイテムの順序を決定するFunctor引数にもテンプレート化しました。ここまでは順調ですね。

あるコンテナの内容を別のコンテナにコピーしたいときに、私が遭遇した小さな問題が発生します。2つのコンテナの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;
}
4

2 に答える 2

2

ItemTypeだけでテンプレート化された基本テンプレートクラスを作成し、そこにデータを保持し、その基本となる本格的な2引数テンプレートサブクラスを作成し、ファンクターに依存しないため、コピー元を基本クラスに配置できます。 。すなわち:

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;-)
};
于 2009-07-28T04:48:40.580 に答える
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;
}
于 2009-07-28T09:55:34.517 に答える