C++ 使用模板指定成员变量

C++ 使用模板指定成员变量,c++,class,templates,C++,Class,Templates,这里我有一个带有类模板的二叉搜索树类: template <class T> class Tree { T* root_ptr; public: void Insert(T* ptr_to_value); }; template <typename T> void Tree<T>::Insert(T* ptr_to_value) { T** temp = &root_ptr; while (*temp) {

这里我有一个带有类模板的二叉搜索树类:

template <class T>
class Tree {
    T* root_ptr;
public:
    void Insert(T* ptr_to_value);
};

template <typename T>
void Tree<T>::Insert(T* ptr_to_value) {
    T** temp = &root_ptr;
    while (*temp) {
        if (ptr_to_value->name <= (*temp)->name)
            temp = &(*temp)->left_ptr;
        else
            temp = &(*temp)->right_ptr;
    }
    (*temp) = ptr_to_value;
}
模板
类树{
T*root\u ptr;
公众:
无效插入(T*ptr_至_值);
};
模板
无效树::插入(T*ptr_到_值){
T**temp=&root\u ptr;
while(*temp){
如果(ptr_至_值->名称)
温度=&(*temp)->左侧;
其他的
温度=&(*temp)->右侧;
}
(*温度)=ptr_至_值;
}

但它指的是
T
类的
name
变量,我可能希望与其他成员变量进行比较。我想要像
模板
这样的东西,这样我就可以初始化树,比如
,或者
,模板参数不必是类型;它们也可以是某些非类型,只要它们是编译常量。指向会员资格的指针

template <class T, auto Ptr>
class Tree {
    T* root_ptr;
public:
    void Insert(T* ptr_to_value);
};

template <typename T>
void Tree<T>::Insert(T* ptr_to_value)
{
    T** temp = &root_ptr;
    while (*temp) {
        if (ptr_to_value->*Ptr <= (*temp)->*Ptr)
            temp = &(*temp)->left_ptr;
        else
            temp = &(*temp)->right_ptr;
    }
    (*temp) = ptr_to_value;
}

// Tree<Foo, &Foo::name> t;
// t.insert(&val);
模板
类树{
T*root\u ptr;
公众:
无效插入(T*ptr_至_值);
};
模板
无效树::插入(T*ptr_到_值)
{
T**temp=&root\u ptr;
while(*temp){
如果(ptr_至_值->*ptr*ptr)
温度=&(*temp)->左侧;
其他的
温度=&(*temp)->右侧;
}
(*温度)=ptr_至_值;
}
//树t;
//t.插入(&val);

与直接在
Insert
方法中进行比较不同,您可以让
保存一个比较函数。这是标准容器采用的方法

例如:

template <typename T, typename Comp = std::less<T>>
class Tree {
    T* root_ptr;
    Comp comp;
public:
    Tree(Comp comp = Comp{})
      : root_ptr{nullptr},
        comp{comp}
    {
    }
    void Insert(T* ptr_to_value);
};

template <typename T, typename Comp>
void Tree<T, Comp>::Insert(T* ptr_to_value) {
    T** temp = &root_ptr;
    while (*temp) {
        if (comp(*ptr_to_value, **temp))
            temp = &(*temp)->left_ptr;
        else
            temp = &(*temp)->right_ptr;
    }
    (*temp) = ptr_to_value;
}

struct Foo {
    int foo;
    Foo* left_ptr;
    Foo* right_ptr;
};

bool operator<(const Foo& left, const Foo& right) {
    return left.foo < right.foo;
}

struct CompareFoosGreater {
    bool operator()(const Foo& left, const Foo& right) {
        return left.foo > right.foo;
    }
};

int main() {
    // Defaults to using std::less, which compares
    // objects using the < operator
    Tree<Foo> foo_tree_less;
    // Use a custom comparator
    Tree<Foo, CompareFoosGreater> foo_tree_greater;
}
模板
类树{
T*root\u ptr;
Comp-Comp;
公众:
树(Comp-Comp=Comp{})
:root_ptr{nullptr},
comp{comp}
{
}
无效插入(T*ptr_至_值);
};
模板
无效树::插入(T*ptr_到_值){
T**temp=&root\u ptr;
while(*temp){
如果(组件(*ptr_至值,**温度))
温度=&(*temp)->左侧;
其他的
温度=&(*temp)->右侧;
}
(*温度)=ptr_至_值;
}
结构Foo{
int foo;
Foo*左_ptr;
Foo*右_ptr;
};
bool操作符right.foo;
}
};
int main(){
//默认使用std::less,它比较
//使用<运算符的对象
树无树无树;
//使用自定义比较器
树富树大;
}
与使用指向成员的指针相比,这有两个优点:

  • 可以比较多个属性
  • 您可以更改元素存储在中的顺序
  • 该功能可以完全在您的类型中进行编码

  • 使用其他成员变量
    什么?你能给我们举个例子吗?如果
    节点
    始终存在,只需将其用作
    成员类型
    节点根_ptr
    ,这样我就可以像
    一样初始化它了。@AlexeiSavitsky我提供了示例用法。如果将函数中的
    ptr
    替换为
    &T::ptr
    ,这样我就可以像
    一样初始化它了,此外,它还禁止使用除
    T
    @AlexeiSavitsky的成员变量之外的任何变量。不,您不能这样做<代码>名称本身不是一件事。