January 28th, 2009 10:42 PM
#1
[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.
January 28th, 2009 11:23 PM
#2
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
January 29th, 2009 03:11 AM
#3
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.
January 29th, 2009 08:45 AM
#4
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
January 31st, 2009 03:19 AM
#5
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 03:27 AM .
Thanks for your help.
January 31st, 2009 07:58 AM
#6
Re: Declara object type based on run time template parameter
>> edgeTypeTrais
>> edgeTypeTraits
Spelling
>> typedef typename edgeTypeTraits<T, edgeType::allVertexVector allVertexVector;
Syntax. Missing a '>'
gg
February 1st, 2009 06:34 AM
#7
Re: Declara object type based on run time template parameter
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
Forum Rules
Click Here to Expand Forum to Full Width
Bookmarks