現在のテンプレートをテンプレートパラメータの1つに対するテンプレートパラメータとして使用する


8

一般的なグラフ構造を作成しようとしていますが、頂点とエッジの間の循環依存関係に遭遇しています。私はVertexクラスとEdgeクラスを次のように定義します。

template<typename EdgeType>
struct Vertex {
    std::vector<EdgeType> successors;
};

template<typename EdgeCostType, typename VertexWrapper>
struct Edge {
    EdgeCostType cost;
    VertexWrapper source;
    VertexWrapper dest;
};

のようなものでインスタンス化したいのですがVertex<Edge<int, std::shared_ptr<decltype(v)>>> v;、明らかにできません。この循環依存関係を解決するにはどうすればよいですか?

編集:

この問題の要約は、現在のテンプレートを現在のテンプレートのテンプレートパラメータの1つに対するテンプレートパラメータとして使用することです。

template<typename VertexWrapper>
struct Vertex {
    std::vector<pair<int, VertexWrapper<Vertex>>> successors;
};

2
template <typename> class VertexWrapper?また、なぜC ++ 11とC ++ 17の両方のタグがあるのですか?どの標準をターゲットにしていますか?
HolyBlackCat

@HolyBlackCat Afaikは両方に適用されますが、最新のものだけを使用する必要がありますか?また、私はあなたが何を意味しているのかtemplate <typename> typename VertexWrapper
わかり

されたVertexWrapper型の引数は、常にフォームのことになってstd::shared_ptr<decltype(v)>some_template_here<decltype(v)>
クルミ

@walnutそれはshared-ptr / unique_ptr / something with operator->のようなものである必要があります
Simon Berens

私はこの質問の権利を読んでいる場合は、「テンプレートテンプレート」パラメータに見たいと思うかもしれません stackoverflow.com/questions/213761/...
ジョー・

回答:


10

テンプレートテンプレートパラメータを使用すると、次のようなことができます。

template<typename EdgeType>
struct Vertex {
    std::vector<EdgeType> successors;
};

template<typename EdgeCostType, template <typename> class VertexWrapper>
struct Edge {
    EdgeCostType cost;
    VertexWrapper<Edge> source;
    VertexWrapper<Edge> dest;
};


using myEdge = Edge<double, Vertex>;
using myVertex = Vertex<myEdge>;

ありがとう!テンプレートテンプレートパラメータに関するTIL
Simon Berens

2

yoursは単純に機能します。(ただし、メンバーベクトルを印刷して初期化する方法がわかりません)

#include <vector>
#include <iostream>  
using namespace std;

template<typename EdgeType>
struct Vertex {
    vector<EdgeType> successors;
};

template<typename EdgeCostType, typename VertexWrapper>
struct Edge {
    EdgeCostType cost;
    VertexWrapper source;
    VertexWrapper dest;
};

int main (){

    Vertex<int> vertx = {{5}};
    Edge<int, decltype(vertx)> ed = {7};

    cout<< ed.cost <<"\n";     //cout<< ed.dest.successors<<"\n";   // not work, ask help!
}

1
アイデアはVertex<Edge<double, Vertex</*..*/>>>... を持つことです
Jarod42

0

Jarod42の答えは機能しますが、2倍のみに制限されます。intたとえば、s を受け入れるより柔軟なものが必要な場合は、次のオプションもあります。

template<class T>
using myEdge = Edge<T, Vertex>;

template<class T>
using myVertex = Vertex<myEdge<T>>;

これにより、何らかの理由で省略形が必要な場合に、他のタイプの数値を使用できます。次に、doubleを使用すると、次のようになります。

myVertex<double> v;

1
これは使用例にすぎません。さらに進むには、私はそうしますtemplate <typename T> struct graph_type { using egde = Edge<T, Vertex>; using vertex = Vertex<edge>; };
Jarod42
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.