0

タイプ T のデータを返すテンプレート Node があります。

template <class T> Node
{
public: 
     virtual const T& GetData() = 0;
};

そして、データへのポインターと実際のデータを含む派生クラス RefNode と ValueNode が必要です。データのコピーを操作するか、ノード内の実際のデータを操作するかを選択できるようにします。

template<class T> class RefNode : public Node<T>
{
public: 
    RefNode(T *_data) : data(_data) { }
    const T& GetData() { return *data; }
protected:
    DataType *data;
};

template<class T> class ValueNode : public Node<T>
{
public: 
    ValueNode(const T&_data) : data(_data) { }
    const T& GetData() { return data; }
protected:
    T data;
};

テンプレートが仮想メソッドを持つことができないことは知っていますが、得たい効果を説明したかっただけです。私が得たかった効果は次のとおりです。

// クラス Vector 用

Vector v, *c;
c = new Vector();
Node<Vector>* node = new RefNode<Vector>(c);
Node<Vector>* node2 = new ValueNode<Vector>(a);

node2->GetData(); //calls ValueNode<Vector>'s GetData();
node->GetData(); //calls RefNode<Vector>'s GetData();

C++ でこの種の動作を実現する方法はありますか?

編集:

GetData() を次のように使用します。

Vector *vecarr[9];

Node<Vector>* nodes[10];
nodes[0] = new RefNode<Vector>(vecarr[0]);
nodes[1] = new ValueNode<Vector>(Vector(2,3)); //non reference vector
nodes[2] = new RefNode<Vector>(vecarr[1]);
nodes[3] = new RefNode<Vector>(vecarr[2]);
.....

void processPositionNodes(Node<Vector> **nodes, int n)
{
   for(int i=0; i< n; i++)  //iterate over all nodes
   {
      Vector vec = nodes[i]->GetData();
      //do something with vec

   }
}

ノードに含まれるデータのタイプを変更できるようにしたいのは、さまざまなタイプのデータ (ベクトル、スカラーなど) を処理するいくつかのグラフ アルゴリズムを実装したいからです。

4

2 に答える 2

0

コメントで指摘されているように、テンプレートは実際に仮想関数を持つことができます。ただし、これで問題が解決するわけではありません。実際、これらの関数には異なる戻り値の型が必要です。

これはあなたの問題に対する可能なテンプレートベースの解決策です。最もエレガントではないかもしれませんが、あなた (私たち) はこれに基づいて作業することができます

#include <iostream>

using namespace std;

template <typename T, template<typename> class Accessor, template<typename> class Traits>
class Node{
    public:
        Node() : data(5.){}
        typedef typename Traits<T>::type getType;
        getType get(){
           return static_cast<Accessor<T>*>(this)->implementation();
        }
        virtual ~Node(){}
    protected:
        T data;
};

template <typename T>
struct TraitsP{
    typedef T* type;
};

template <typename T>
class PointerAccessor : public Node<T, PointerAccessor, TraitsP>{
    public:
        typename TraitsP<T>::type implementation(){
            return &(Node<T, PointerAccessor, TraitsP>::data);
        }
};

template <typename T>
struct TraitsD{
    typedef T type;
};

template <typename T>
class DirectAccessor : public Node<T, DirectAccessor, TraitsD>{
    public:
        typename TraitsD<T>::type implementation(){
            T ret = Node<T, DirectAccessor, TraitsD>::data;
            return ret;
        }
};

int main(){
    auto np = new PointerAccessor<double>();
    double* p = np->get();
    cout << *p << endl;

    auto np2 = new DirectAccessor<double>();
    double d = np2->get();
    cout << d << endl;
}

このソリューションで奇妙に思えるのは、PointerAccessor が Node\<..., PointerAccessor, ...> から派生していることです。これはいわゆるCuriously Recurring Template Pattern (CRTP)です。

于 2013-07-09T15:02:28.620 に答える