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实例;
此实现的问题(或优点?)在于,具有一种指针的节点可以容纳具有另一种指针的子节点