【问题标题】:Class template with both pointer type and regular type具有指针类型和常规类型的类模板
【发布时间】:2013-01-25 19:20:59
【问题描述】:

我为它的值类型定义了一个带有模板的 Node 类

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

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

问题是,某些函数可能需要根据T 是否为指针类型而表现出不同的行为。例如,print 应该是 cout &lt;&lt; *v,否则是 cout &lt;&lt; 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&lt;int&gt; or Node&lt;int *&gt;来选择合适的定义,但是问题就变成了,两个定义会共享很多代码。我想知道是否有更好的方法来实现这一点。

【问题讨论】:

  • 你能解释一下为什么你认为 Node 会比 Node 更方便吗?例如,如果这个节点被用作树节点,那么 Node* 将是一个更好的解决方案
  • Foo 是全局分配/使用的对象。仅将 Foo* 传递给数据字段不会涉及重新创建对象。我只是说 Node 的类型 T,而不是 Node 本身。
  • 嗨,你解决了这个问题吗?我处于同样的情况,我想要不同的析构函数行为。特别是,如果是参数值,我只想删除节点,但如果是指针,我想先删除那个指针,然后再删除节点自身。

标签: c++ templates pointers


【解决方案1】:

看到这个:C++ template specialization, calling methods on types that could be pointers or references unambiguously

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

CRTP 可能有助于减少代码重复,同时允许两个专业化的通用代码没有任何开销。

请注意,当您有时使用指针,有时使用实例时,所有权语义会变得很棘手——val 的生命周期是多少,如果它有时是参数的指针,有时是参数的副本,以及如何执行?

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2016-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-16
      • 2018-12-04
      • 2016-08-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多