我可以做些什么来完成这项工作:
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但这需要我有参与者类的显式构造函数)。我还需要传递或计算一个&#34;所有者&#34;指向Reference类的指针。我在这里留下了这个问题,因为我想专注于自引用模板方面。
最简单的想法是boost :: bimap。但是bimap的问题在于我不想要封闭的bimap而只是它的左右两部分。 bimap也不可行,因为它会导致一个单一的bimap管理特定关系的所有关联。它可能会阻止大量对象减慢对它的操作。
答案 0 :(得分:2)
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 );
}
};
编辑:再一次,我不确定你的最终目标是什么。这是我认为你想要的解决方案,或者至少是你可能用来实现你的设计的一些暗示。我提出的唯一要求是TAddress
和TPartner
都具有相同名称的函数。看看这是否是你需要的。原则上,您可以创建一个帮助器类并使用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 );
}
答案 1 :(得分:1)
问题是,我想要实现的目标在C ++中是不可能的,至少不是模板和我所针对的代码和类的数量(读取:每个成员的单行代码)。它始于编译器需要前向声明和完全定义的类型,这使得按值成员和模板参数不可能(在循环依赖的情况下)。然后,当该成员的类尚未完全定义时,不可能将成员指针作为模板arg。所有这些的根本原因是编译器的工作原理:它是单通道。我无能为力。
解决方案是使用by-reference成员或OO样式基类或boost :: any样式容器来避免模板。对于后者2,可能有价值成员。