C++ C++;模板问题
我定义了一个通用树节点类,如下所示:C++ C++;模板问题,c++,metaprogramming,C++,Metaprogramming,我定义了一个通用树节点类,如下所示: template<class DataType> class GenericNode { public: GenericNode() {} GenericNode(const DataType & inData) : mData(inData){} const DataType & data() const { return mData; } void setData(const Da
template<class DataType>
class GenericNode
{
public:
GenericNode() {}
GenericNode(const DataType & inData) : mData(inData){}
const DataType & data() const
{ return mData; }
void setData(const DataType & inData)
{ mData = inData; }
size_t getChildCount() const
{ return mChildren.size(); }
const GenericNode * getChild(size_t idx) const
{ return mChildren[idx]; }
GenericNode * getChild(size_t idx)
{ return mChildren[idx]; }
void addChild(GenericNode * inItem)
{ mChildren.push_back(inItem); }
private:
DataType mData;
typedef std::vector<GenericNode*> Children;
Children mChildren;
};
typedef GenericNode<std::string> TreeItemInfo;
模板
类GenericNode
{
公众:
GenericNode(){}
GenericNode(const数据类型和inData):mData(inData){}
常量数据类型&data()常量
{返回mData;}
void setData(常量数据类型和索引数据)
{mData=inData;}
大小\u t getChildCount()常量
{return mChildren.size();}
const GenericNode*getChild(size\t idx)const
{返回mChildren[idx];}
GenericNode*getChild(大小\u t idx)
{返回mChildren[idx];}
void addChild(GenericNode*inItem)
{mChildren.push_back(inItem);}
私人:
数据类型mData;
typedef-std::矢量子对象;
儿童;
};
typedef GenericNode TreeItemInfo;
我希望通过使子指针类型可自定义,使其更通用。例如,允许使用智能指针类型。我天真地试过:
template<class DataType, class ChildPtr>
class GenericNode
{
public:
GenericNode() {}
GenericNode(const DataType & inData) : mData(inData){}
const DataType & data() const
{ return mData; }
void setData(const DataType & inData)
{ mData = inData; }
size_t getChildCount() const
{ return mChildren.size(); }
const ChildPtr getChild(size_t idx) const
{ return mChildren[idx]; }
ChildPtr getChild(size_t idx)
{ return mChildren[idx]; }
void addChild(ChildPtr inItem)
{ mChildren.push_back(inItem); }
private:
DataType mData;
typedef std::vector<ChildPtr> Children;
Children mChildren;
};
typedef GenericNode<std::string, GenericNode<std::string > * > TreeItemInfo;
模板
类GenericNode
{
公众:
GenericNode(){}
GenericNode(const数据类型和inData):mData(inData){}
常量数据类型&data()常量
{返回mData;}
void setData(常量数据类型和索引数据)
{mData=inData;}
大小\u t getChildCount()常量
{return mChildren.size();}
const ChildPtr getChild(size\t idx)const
{返回mChildren[idx];}
ChildPtr getChild(大小\u t idx)
{返回mChildren[idx];}
void addChild(ChildPtr inItem)
{mChildren.push_back(inItem);}
私人:
数据类型mData;
typedef-std::矢量子对象;
儿童;
};
typedef GenericNode TreeItemInfo;
但是,这当然不行,因为我需要为第二个参数指定第二个参数,为第二个参数指定第二个参数,等等。。。进入永恒
有办法解决这个难题吗
编辑
我根据@Asaf的答案找到了一个解决方案。对于那些感兴趣的人,下面是一个完整的代码示例(欢迎评论)
编辑2
我修改了接口,以便在外部始终使用原始指针
#include <string>
#include <vector>
#include <boost/shared_ptr.hpp>
#include <assert.h>
template <class PointeeType>
struct NormalPointerPolicy
{
typedef PointeeType* PointerType;
static PointeeType* getRaw(PointerType p)
{
return p;
}
};
template <class PointeeType>
struct SharedPointerPolicy
{
typedef boost::shared_ptr<PointeeType> PointerType;
static PointeeType* getRaw(PointerType p)
{
return p.get();
}
};
template <class DataType, template <class> class PointerPolicy>
class GenericNode
{
public:
GenericNode() { }
GenericNode(const DataType & inData) : mData(inData) { }
typedef GenericNode<DataType, PointerPolicy> This;
typedef typename PointerPolicy<This>::PointerType ChildPtr;
const This * getChild(size_t idx) const
{ return PointerPolicy<This>::getRaw(mChildren[idx]); }
This * getChild(size_t idx)
{ return PointerPolicy<This>::getRaw(mChildren[idx]); }
void addChild(This * inItem)
{
ChildPtr item(inItem);
mChildren.push_back(item);
}
const DataType & data() const
{ return mData; }
void setData(const DataType & inData)
{ mData = inData; }
private:
DataType mData;
std::vector<ChildPtr> mChildren;
};
typedef GenericNode<std::string, NormalPointerPolicy> SimpleNode;
typedef GenericNode<std::string, SharedPointerPolicy> SmartNode;
int main()
{
SimpleNode simpleNode;
simpleNode.addChild(new SimpleNode("test1"));
simpleNode.addChild(new SimpleNode("test2"));
SimpleNode * a = simpleNode.getChild(0);
assert(a->data() == "test1");
const SimpleNode * b = static_cast<const SimpleNode>(simpleNode).getChild(1);
assert(b->data() == "test2");
SmartNode smartNode;
smartNode.addChild(new SmartNode("test3"));
smartNode.addChild(new SmartNode("test4"));
SmartNode * c = smartNode.getChild(0);
assert(c->data() == "test3");
SmartNode * d = static_cast<const SmartNode>(smartNode).getChild(1);
assert(d->data() == "test4");
return 0;
}
#包括
#包括
#包括
#包括
模板
结构NormalPointerPolicy
{
typedef PointeeType*PointerType;
静态指针类型*getRaw(指针类型p)
{
返回p;
}
};
模板
结构SharedPointerPolicy
{
typedef boost::共享指针类型;
静态指针类型*getRaw(指针类型p)
{
返回p.get();
}
};
模板
类GenericNode
{
公众:
GenericNode(){}
GenericNode(const数据类型和inData):mData(inData){}
typedef GenericNode此节点;
typedef typename PointerPolicy::PointerType ChildPtr;
const This*getChild(size\t idx)const
{返回点策略::getRaw(mChildren[idx]);}
此*getChild(大小\u t idx)
{返回点策略::getRaw(mChildren[idx]);}
void addChild(此*inItem)
{
儿童PTR项目(初始项);
McChildren.推回(项目);
}
常量数据类型&data()常量
{返回mData;}
void setData(常量数据类型和索引数据)
{mData=inData;}
私人:
数据类型mData;
性病:病媒儿童;
};
typedef GenericNode SimpleNode;
typedef GenericNode智能节点;
int main()
{
单纯形单纯形;
addChild(新的simpleNode(“test1”));
addChild(新的simpleNode(“test2”));
SimpleNode*a=SimpleNode.getChild(0);
断言(a->data()=“test1”);
const SimpleNode*b=静态_转换(SimpleNode).getChild(1);
断言(b->data()=“test2”);
智能节点;
addChild(新的smartNode(“test3”));
addChild(新的smartNode(“test4”));
SmartNode*c=SmartNode.getChild(0);
断言(c->data()=“test3”);
SmartNode*d=静态_转换(SmartNode).getChild(1);
断言(d->data()=“test4”);
返回0;
}
不是你看待它的方式。你应该在这里把某种继承结合起来。
试试这个,例如:
template <class PointeeType>
struct NormalPointerPolicy
{
typedef PointeeType* PointerType;
};
template <class PointeeType>
struct SmartPointerPolicy
{
typedef MySmartPtrClass<PointeeType> PointerType;
};
template <class DataType>
class BaseGenericNode
{
public:
BaseGenericNode() {}
BaseGenericNode(const DataType & inData) : mData(inData){}
const DataType & data() const
{ return mData; }
void setData(const DataType & inData)
{ mData = inData; }
protected:
DataType mData;
};
template <class DataType, template <class> class PointerPolicy>
class GenericNode : public BaseGenericNode<DataType>
{
typedef typename PointerPolicy<BaseGenericNode<DataType> >::PointerType ChildPtr;
private:
typedef std::vector<ChildPtr> Children;
Children mChildren;
};
模板
结构NormalPointerPolicy
{
typedef PointeeType*PointerType;
};
模板
结构SmartPointerPolicy
{
typedef MySmartPtrClass指针类型;
};
模板
类BaseGenericNode
{
公众:
BaseGenericNode(){}
BaseGenericNode(const数据类型和inData):mData(inData){}
常量数据类型&data()常量
{返回mData;}
void setData(常量数据类型和索引数据)
{mData=inData;}
受保护的:
数据类型mData;
};
模板
类GenericNode:公共BaseGenericNode
{
typedef typename PointerPolicy::PointerType ChildPtr;
私人:
typedef-std::矢量子对象;
儿童;
};
GenericNode是实际的节点类型,它包含基类型“BaseGenericNode”。基类型保存实际数据(及其相关功能),派生类保存到其他节点的链接。
指针的实际外观有两个模板策略类,您可以这样使用它们:
GenericNode<int, NormalPointerPolicy> instance;
GenericNode<int, SmartPointerPolicy> instance;
GenericNode实例;
GenericNode实例;
此实现的问题(或优点?)在于,具有一种指针的节点可以容纳具有另一种指针的子节点