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

时间:2013-01-25 19:21:00

标签: c++ templates pointers

我为其值类型

定义了一个带有模板的Node类
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 << *vcout << 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 *>来选择合适的定义但是问题变成了,这两个定义将共享许多代码。我想知道是否有更好的方法来实现这一目标。

2 个答案:

答案 0 :(得分:5)

请参阅:C++ template specialization, calling methods on types that could be pointers or references unambiguously

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

CRTP可能有助于减少代码重复,允许两个特化的公共代码,而且没有任何开销。

请注意,当您有时使用指针(有时是实例)时,所有权语义会变得棘手 - 如果有时候它是参数的指针,那么val的生命周期是什么,有时它是论证,以及如何执行它?

答案 1 :(得分:0)

嗯,还有另一种方法。您应该使用类型特征,它们是在编译时评估的。这就是修改方法。

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;
    }
}