CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7
  1. #1
    Join Date
    Apr 2007
    Location
    Mars NASA Station
    Posts
    1,436

    [RESOLVED] Declara object type based on run time template parameter

    Hello to all expert C++ programmer,

    Code:
    template <typename T, class edgeType = edge>
    class graph
    {	
    public:
    /*
      shared_ptr's template parameter is object 
      and not pointer to object
    */
    	typedef boost::shared_ptr<vertex<T> > 
    		vertexPtr;
    private:
    
    	std::vector<vertexPtr> allVertex;
    I want that when different type of edgeType is supplied, then i want instantiated different type of vertexPtr.

    I have two type of edgeType, one is edge(undirected) and arcs(Directed).

    Whenever user supplied, graph<int, arcs> DAG;, then in the

    Code:
    typedef boost::shared_ptr<arcs> arcsPtr;
    typedef boost::shared_ptr<vertex<T, arcsPtr> > vertexPtr;
    should have arcsPtr.

    Then, if user graph<int> supplied this, then default vertexPtr should be used.

    I hope this make sense to you all.

    Traits or CRTP or any design patterns is greatly appreciated by me.

    The purpose of this question is to declare a graph class template that works with directed and undirected class based on template parameter.

    graph<int> grp -- Undirected;
    graph(int, arcs> -- directed;


    Thanks for your help.
    Thanks for your help.

  2. #2
    Join Date
    Nov 2003
    Posts
    1,902

    Re: Declara object type based on run time template parameter

    Code:
    typedef boost::shared_ptr<edgeType> edgeTypePtr;
    typedef boost::shared_ptr<vertex<T, edgeTypePtr> > vertexPtr;
    I think that's what you want.

    gg

  3. #3
    Join Date
    Apr 2007
    Location
    Mars NASA Station
    Posts
    1,436

    Re: Declara object type based on run time template parameter

    Let me rephrase the question.

    Code:
    If i supplied graph<int>, then in graph 
         typedef  boost::shared_ptr<vertex<T> > vertexPtr;
         std::vector<vertexPtr> allVertex;(Undirected graph)
    else 
       graph<int, arcs>
       then i need 
       typedef  boost::shared_ptr<vertex<T, arcs> > arcsVertexPtr;
        std::vector<arcsVertexPtr> allVertex;(directed graph)
    I hope this make more sense.

    Thanks.
    Thanks for your help.

  4. #4
    Join Date
    Nov 2003
    Posts
    1,902

    Re: Declara object type based on run time template parameter

    Ah. Then you can use a traits-type template with specialization to "choose" the appropriate type:
    Code:
    template <typename T, typename edgeType>
    struct edgeTypeTraits; // no impl. - just for specialization
    
    template <typename T>
    struct edgeTypeTraits<T, edge> // specialized for edge
    {
        typedef boost::shared_ptr<vertex<T> > vertexPtr_t;
        typedef std::vector<vertexPtr_t>      allVertex_t;
    };//edgeTypeTraits<T, edge>
    
    template <typename T>
    struct edgeTypeTraits<T, arcs> // specialized for arcs
    {
        typedef boost::shared_ptr<vertex<T, arcs> > vertexPtr_t;
        typedef std::vector<vertexPtr_t>            allVertex_t;
    };//edgeTypeTraits<T, edge>
    
    template <typename T, typename edgeType = edge>
    struct graph
    {
        typedef typename edgeTypeTraits<T, edgeType>::vertexPtr_t vertexPtr_t;
        typedef typename edgeTypeTraits<T, edgeType>::allVertex_t allVertex_t;
    
        vertexPtr_t m_vp;
        allVertex_t m_av;
    };//graph
    gg

  5. #5
    Join Date
    Apr 2007
    Location
    Mars NASA Station
    Posts
    1,436

    Re: Declara object type based on run time template parameter

    I have did what you show but but this doesn't clear it the problem due to numerous compilation problem.

    My code:

    Code:
    #ifndef EDGETYPETRAITS_H
    #define EDGETYPETRAITS_H
    
    
    #include <boost/shared_ptr.hpp>
    #include "Arcs.h"
    #include "Edge.h"
    
    
    template <typename T, typename link = edgePtr>
    class vertex;
    
    
    // Base class no definition
    template <typename T, typename edgeType>
    class edgeTypeTrais;
    
    
    // Partial Specialization
    template <typename T>
    class edgeTypeTrais<T, edge> 
    {
    public:
    	typedef boost::shared_ptr<vertex<int> > vertexPtr; 
    	typedef std::vector<vertexPtr> allVertexVector;
    };
    
    
    // Partial Specialization
    template <typename T>
    class edgeTypeTraits<T, arcs> ---> [bold]Error[/bold]
    {
    public:
    	typedef boost::shared_ptr<vertex<int, arcs> > vertexPtr; 
    	typedef std::vector<vertexPtr> allVertexVector;
    };
    
    #endif
    The error appear at second edgeTypeTraits class.

    If i uncomment the second edgeTypeTraits class,

    error appear at here
    Code:
    typedef typename edgeTypeTraits<T, edgeType::allVertexVector allVertexVector;
    
    allVertexVector allVertex;
    error C2143: syntax error : missing ';' before '<'
    error C2059: syntax error : '<'
    error C2143: syntax error : missing ';' before '{'
    error C2447: '{' : missing function header (old-style formal list?)
    error C2977: 'edgeTypeTraits' : too many template arguments
    error C2039: 'vertexPtr' : is not a member of 'edgeTypeTraits'
    error C2146: syntax error : missing ';' before identifier 'vertexPtr'
    error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    error C2868: 'graph<T,edgeType>::vertexPtr' : illegal syntax for using-declaration; expected qualified-name
    warning C4346: 'edgeType::allVertexVector' : dependent name is not a type
    error C2146: syntax error : missing ',' before identifier 'allVertexVector'
    error C2065: 'allVertexVector' : undeclared identifier
    error C2143: syntax error : missing '>' before ';'
    error C2208: 'edgeTypeTraits' : no members defined using this type
    error C2146: syntax error : missing ';' before identifier 'allVertex'
    Error 16 error C4430: missing type specifier - int assumed. Note: C++ does not support default-int d:\c++\data structure\graph\graph\graph.h 31
    error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    error C2977: 'edgeTypeTraits' : too many template arguments
    Error 19 error C2955: 'edgeTypeTraits' : use of class template requires template argument list
    error C2027: use of undefined type 'edgeTypeTraits'
    error C2146: syntax error : missing ';' before identifier 'vertexPtr'
    error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    error C2602: 'graph<T>::vertexPtr' is not a member of a base class of 'graph<T>'
    error C2868: 'graph<T>::vertexPtr' : illegal syntax for using-declaration; expected qualified-name d:\c++\data structure\graph\graph\graph.h 26
    error C2039: 'allVertexVector' : is not a member of 'edge'
    Error 26 error C2146: syntax error : missing ',' before identifier 'allVertexVector' d:\c++\data structure\graph\graph\graph.h 30
    error C2143: syntax error : missing '>' before ';'
    error C2208: 'edgeTypeTraits' : no members defined using this type0
    error C2146: syntax error : missing ';' before identifier 'allVertex' d:\c++\data structure\graph\graph\graph.h 31
    Error 30 error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
    error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

    MS VS 2005

    My complete code:

    Code:
    
    #ifndef ARCS_H
    #define ARCS_H
    
    
    #include <string>
    #include <boost/shared_ptr.hpp>
    
    
    class arcs
    {
    private:
    	int weightage;
    	std::string toVertex;
    
    public:
    	arcs();
    	~arcs();
    };
    #endif
    
    #include <algorithm>
    #include <string>
    #include "Arcs.h"
    
    
    // =============================================
    arcs::arcs() : weightage(int (0)), toVertex(std::string(""))
    {
    }
    // =============================================
    arcs::~arcs()
    {
    }
    
    #ifndef EDGE_H
    #define EDGE_H
    
    #include <string>
    
    /* arcs is directed edge
       edge is undirected edge 
    */
    
    class edge
    {
    private:
    	// Path's cost
    	int weightage;
    	std::string firstVertexID;
    	std::string secondVertexID;
    
    	/*	An edge in an undirected graph 
    		is a set of two vertices
    		
    		An edge is placed twice, once for A->B
    		B->A
    	
    	*/
    
    public:
    	edge();
    	edge(int);
    	edge(const edge&);
    	edge& operator=(const edge&);
    
    	void setWeightage(int);
    	int getWeightage();
    
    	void setFirstVertexID(const std::string&);
    	void setSecondVertexID(const std::string&);
    
    	std::string getFirstVertexID();
    	std::string getSecondVertexID();
    
    	~edge();
    };
    
    #endif
    
    #include <algorithm>
    #include <string>
    #include "Edge.h"
    
    // =============================================
    edge::edge() : weightage(0), 
    		firstVertexID(std::string("")), 
    		secondVertexID(std::string(""))
    {
    }
    // =============================================
    edge::edge(int myWeightage) 
    	: weightage(myWeightage), 
    		firstVertexID(std::string("")), 
    		secondVertexID(std::string("")) 
    {
    }
    // =============================================
    edge::edge(const edge& that) 
    	: weightage(that.weightage), 
    		firstVertexID(std::string(that.firstVertexID)), 
    		secondVertexID(std::string(that.secondVertexID)) 
    {
    }
    // =============================================
    edge& edge::operator=(const edge& that)
    {
    	if (this != &that)
    	{
    		edge tempEdge(that.weightage);
    		tempEdge.firstVertexID = that.firstVertexID;
    		tempEdge.secondVertexID = that.secondVertexID;
    
    		std::swap(this->weightage, 
    			tempEdge.weightage);
    	}
    	return *this;
    }
    // =============================================
    edge::~edge()
    {
    }
    // =============================================
    void edge::setWeightage(int userWeightage)
    {
    	weightage = userWeightage;
    }
    // =============================================
    int edge::getWeightage()
    {
    	return this->weightage;
    }
    // =============================================
    void edge::setFirstVertexID(const std::string& userVertexID)
    {
    	firstVertexID = userVertexID;
    }
    // =============================================
    void edge::setSecondVertexID(const std::string& userVertexID)
    {
    	secondVertexID = userVertexID;
    }
    // =============================================
    std::string edge::getFirstVertexID()
    {
    	return firstVertexID;
    }
    // =============================================
    std::string edge::getSecondVertexID()
    {
    	return secondVertexID;
    }
    // =============================================
    
    
    #ifndef VERTEX_H
    #define VERTEX_H
    
    
    #include <vector>
    #include <string>
    #include <boost/shared_ptr.hpp>
    
    #include "Edge.h"
    
    typedef boost::shared_ptr<edge> edgePtr;
    
    
    
    template <typename T, typename link = edgePtr>
    class vertex
    {
    public:
    
    	typedef boost::shared_ptr<vertex<T> > vertexPtr;
    
    private:
    	// Number of edge incident from this vertex
    	int degree;
    	// Distance from this vertex to another vertex
    	int fromDistance; 
    	// Vertex name
    	std::string vertexID;
    	// Vertex information
    	T element;
    	
    	/* 
    		This used to represent/store all edges 
    		incident(attach/link) from/to this vertex
    	*/	
    	std::vector<link> incidentEdge;
    	std::vector<vertexPtr> incidentVertex;
    
    	
    	
    public:
    	
    	vertex();
    	vertex(const T& );
    
    	void decreaseDegree();
    
    	void setDegree();
    	void setDegree(int);
    
    	void setFromDistance(int);
    	void setVertexID(const std::string& );
    	void setElement(const T&);
    	void setIncidentEdge(boost::shared_ptr<edge>& );
    	void setIncidentVertex(boost::shared_ptr<vertex>& );
    	
    	void deleteEdge(int);
    	void deleteVertex(int);
    
    	int getDegree();
    	int getFromDistance();
    	const std::string getVertexID();
    	const T getElement();
    	std::vector<link>& getIncidentEdge();
    	std::vector<typename vertex<T>::vertexPtr>& getIncidentVertex();
    
    	~vertex();
    };
    
    // =============================================
    template <typename T, typename link>
    vertex<T, link>::vertex() : degree(0),
    				fromDistance(0)
    				vertexID(std::string("")), 
    				element(T()),
    				incidentEdge(vector<link>()), 
    				incidentVertex(vector<vertexPtr>())
    {
    }
    // =============================================
    template <typename T, typename link>
    vertex<T, link>::vertex(const T& info) : degree(0), 
    				fromDistance(0), vertexID(std::string()), 
    				element(info),
    				incidentEdge(vector<link>()), 
    				incidentVertex(vector<vertexPtr>())
    {
    }
    // =============================================
    template <typename T, typename link>
    vertex<T, link>::~vertex()
    {
    }
    // =============================================
    template <typename T, typename link>
    void vertex<T, link>::decreaseDegree()
    {
    	--degree;
    }
    // =============================================
    template <typename T, typename link>
    void vertex<T, link>::setDegree()
    {
    	++degree;
    }
    // =============================================
    template <typename T, typename link>
    void vertex<T, link>::setFromDistance(int userDistance)
    {
    	fromDistance = userDistance;
    }
    // =============================================
    template <typename T, typename link>
    void vertex<T, link>::setDegree(int myDegree)
    {
    	degree = myDegree;
    }
    // =============================================
    template <typename T, typename link>
    void vertex<T, link>::setVertexID(const std::string& vertexName)
    {
    	vertexID = vertexName;
    }
    // =============================================
    template <typename T, typename link>
    void vertex<T, link>::setElement(const T& info)
    {
    	element = info;
    }
    // =============================================
    template <typename T, typename link>
    void vertex<T, link>::setIncidentEdge(boost::shared_ptr<edge>& userEdge)
    {
    	incidentEdge.push_back(userEdge);
    }
    // =============================================
    template <typename T, typename link>
    void vertex<T, link>::setIncidentVertex(boost::shared_ptr<vertex>& userVertex)
    {
    	incidentVertex.push_back(userVertex);
    }
    // =============================================
    template <typename T, typename link>
    void vertex<T, link>::deleteEdge(int position)
    {
    	incidentEdge.erase(incidentEdge.begin() + position);
    }
    // =============================================
    template <typename T, typename link>
    void vertex<T, link>::deleteVertex(int position)
    {
    	incidentVertex.erase(incidentVertex.begin() + position);
    }
    // =============================================
    template <typename T, typename link>
    int vertex<T, link>::getDegree()
    {
    	return this->degree;
    }	
    // =============================================
    template <typename T, typename link>
    int vertex<T, link>::getFromDistance()
    {
    	return this->fromDistance;
    }
    // =============================================
    template <typename T, typename link>
    const std::string vertex<T, link>::getVertexID()
    {
    	return this->vertexID;
    }
    // =============================================
    template <typename T, typename link>
    const T vertex<T, link>::getElement()
    {
    	return this->element;
    }
    // =============================================
    template <typename T, typename link>
    std::vector<link>& vertex<T, link>::getIncidentEdge()
    {
    	return this->incidentEdge;
    }
    // =============================================
    template <typename T, typename link>
    std::vector<typename vertex<T>::vertexPtr>& vertex<T, link>::getIncidentVertex()
    {
    	return this->incidentVertex;
    }
    
    
    #endif
    
    #ifndef GRAPH_H
    #define GRAPH_H
    
    #include <vector>
    #include <queue>
    #include <limits>
    
    #include "EdgeTypeTraits.h"
    
    // Forward Declaration minimize file dependecies
    class edge;
    
    template <typename T, typename link = edgePtr>
    class vertex;
    
    
    
    template <typename T, class edgeType = edge>
    class graph
    {	
    public:
    /*
      shared_ptr's template parameter is object 
      and not pointer to object
    */
    	typedef typename edgeTypeTraits<T, edgeType>::vertexPtr vertexPtr;
    
    private:
    
    	typedef typename edgeTypeTraits<T, edgeType::allVertexVector allVertexVector;
    	allVertexVector allVertex;
    };
    
    #endif

    Thanks.
    Last edited by Peter_APIIT; January 31st, 2009 at 04:27 AM.
    Thanks for your help.

  6. #6
    Join Date
    Nov 2003
    Posts
    1,902

    Re: Declara object type based on run time template parameter

    >> edgeTypeTrais
    >> edgeTypeTraits
    Spelling

    >> typedef typename edgeTypeTraits<T, edgeType::allVertexVector allVertexVector;
    Syntax. Missing a '>'

    gg

  7. #7
    Join Date
    Apr 2007
    Location
    Mars NASA Station
    Posts
    1,436

    Re: Declara object type based on run time template parameter

    Good eyes spot.

    Thanks.
    Thanks for your help.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured