簡體   English   中英

模板參數中的自引用模板

[英]Self-referencing Template in Template Argument

我能做些什么來完成這項工作:

template<class C, class V, Test V::*>
class Test {
};

它給了我編譯器錯誤:

unknown type name 'Test'

它現在是一個自引用模板,似乎不可能。 有什么辦法可以讓它發揮作用?

編輯:

這就是我需要的東西。 我想用最少的編碼工作來實現雙向(思考父子)關系模式。

template <class O, class T, Reference<T, O, Reference O::*> T::* opposite>
class Reference
{
    T **data;
    int count;
public:
    Reference(): data(new T*[N]), count(0) {}
    ~Reference() {delete[] data;}
    Reference &add(T *t) {
        handleOtherSide();
        return link(t);
    }
    // a lot of stuff to implement this
};

那是集合類。 以下是它的使用方法:

class Partner
{
public:
    Reference<Partner, Address, &Address::partner> addresses;
};

class Address
{
public:
    Reference<Address, Partner, &Partner::addresses> partner;
};

我的目標是讓參考工作所需的一切都作為模板參數提供,這樣就不需要為像Partner和Address這樣的類提供構造函數(目前我提供相反的成員指針作為構造函數arg,但這需要我有參與者類的顯式構造函數)。 我還需要傳入或計算一個指向Reference類的“owner”指針。 我在這里留下了這個問題因為我想專注於自引用模板方面。

最簡單的想法是boost :: bimap。 但是bimap的問題在於我不想要封閉的bimap,而只需要它的左右兩部分。 bimap也不可行,因為它會導致一個單一的bimap管理特定關系的所有關聯。 它可能會容納大量對象,從而減慢對它的操作。

你在找這樣的東西嗎? 它不是自引用模板,但您可以將派生類指定為基類的模板類型,基類可以調用派生方法等:

template< typename PType, typename PDerived >
class TBase
{
  //do stuff with TDerived
 public:
  bool foo( void )
  {
   return ( static_cast< PDerived* > ( this )->bar() );
  }
};

template< typename PType >
class TDerived : public TBase< PType, TDerived< PType > >
{
  friend class TBase< PType, TDerived< PType > > ;
  //do stuff
 protected:
  bool bar( void )
  {
   return ( true );
  }
};

編輯:再一次,我不確定你的最終目標是什么。 這是我認為你想要的解決方案,或者至少是你可能用來實現你的設計的一些暗示。 我提出的唯一要求是TAddressTPartner都具有相同名稱的功能。 看看這是否是你需要的。 原則上,您可以創建一個幫助器類並使用CRTP通過指針訪問成員函數,但我認為您並不需要它。

template< typename PType1, typename PType2 >
class TReference
{
 public:
  int mFlag;

  TReference() :
   mFlag( 0 )
  {
  }
  TReference( int fFlag ) :
   mFlag( fFlag )
  {
   std::cout << "Creating reference " << PType1::sName << " -> " << PType2::sName << "." << std::endl;
  }
  TReference< PType2, PType1 > AccessOpposite( void )
  {
   PType2 lTmp;
   lTmp.Opposite();

   return TReference< PType2, PType1 > ( -1 );
  }
};

class TPartner;

class TAddress
{
 public:
  static const char* sName;
  TReference< TAddress, TPartner > mRef;

  void Opposite( void )
  {
   std::cout << sName << "::Opposite" << std::endl;
  }
};

class TPartner
{
 public:
  static const char* sName;
  TReference< TPartner, TAddress > mRef;

  TReference< TAddress, TPartner > Opposite( void )
  {
   std::cout << sName << "::Opposite" << std::endl;
  }
};

const char* TAddress::sName = "TAddress";
const char* TPartner::sName = "TPartner";

int main( void )
{
 TAddress lAddress;
 TPartner lPartner;

 std::cout << lAddress.mRef.mFlag << " " << lPartner.mRef.mFlag << std::endl;

 lPartner.mRef = lAddress.mRef.AccessOpposite();

 std::cout << lAddress.mRef.mFlag << " " << lPartner.mRef.mFlag << std::endl;

 return ( 0 );
}

問題是,我想要實現的目標在C ++中是不可能的,至少不是模板和我所針對的代碼和類的數量(讀取:每個成員的單行代碼)。 它始於編譯器需要前向聲明和完全定義的類型,這使得按值成員和模板參數不可能(在循環依賴的情況下)。 然后,當該成員的類尚未完全定義時,不可能將成員指針作為模板arg。 所有這些的根本原因是編譯器的工作原理:它是單通道。 我無能為力。

解決方案是使用by-reference成員或OO樣式基類或boost :: any樣式容器來避免模板。 對於后者2,可能有價值成員。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM