同时具有指针类型和常规类型的类模板

Class template with both pointer type and regular type

本文关键字:类型 常规 指针      更新时间:2023-10-16

>我用模板定义一个节点类作为其值类型

template<class T>
class Node {
  T val;
  public:
    Node (T & v) : val (v) {}
    ...
    void print() { cout << v << endl; }
}

大多数时候,感兴趣的节点值将是一个对象类,比如class Foo。在这种情况下,使用Node<Foo *>会更方便。但也可能是节点将保持原始时间,比如int。然后使用Node<int>就足够了。

问题是,某些函数可能需要根据T是否为指针类型而采取不同的行为。例如,print应该cout << *v,否则cout << v

我尝试的是定义两者:

template<class T>
class Node {
  T val;
  public:
    Node (T & v) : val (v) {}
    ...
    void print() { cout << v << endl; }
}
template<class T>
class Node<T*> {
  T* val;
  public:
    Node (T* v) : val (v) {}
    ...
    void print() { cout << *v << endl; }
}

它现在可以根据它是否Node<int> or Node<int *>来选择适当的定义 但问题是,这两个定义将共享许多代码。我想知道是否有更好的方法来实现这一目标。

请参阅以下内容: C++模板专用化,对可以是指针或引用的类型明确调用方法

相同的技术应该在这里起作用,允许您在这两种情况下将val作为引用(或指针)统一处理。

CRTP 可以帮助减少代码重复,允许两个专用化的通用代码,而没有任何开销。

请注意,当你有时使用指针,有时

使用实例时,所有权语义会变得棘手——如果有时它是参数的指针,有时它是参数的副本,那么val的生存期是多少,你如何强制执行它?

嗯,还有另一种方法可以做到这一点。您应该使用类型特征,它们在编译时进行评估。这是您可以修改的方式。

template<class T>
class Node {
  T val;
  public:
    Node (T & v) : val (v) {}
    ...
    void print() { 
      if(std::is_pointer<T>::value)
        cout << *v << endl;
      else
        cout << v << endl;
    }
}