Undefined Reference, Overloaded Operators, What?
Sep 13, 2014 at 7:44pm UTC
This is for the same code as I mentioned in the earlier two questions. In this case, I need to figure out how to make a custom hash function so I can use the class as a key in an unordered_multimap. Note that Connector already has a valid hash function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
#ifndef VERTEX_H
#define VERTEX_H
#include <memory>
#include <unordered_set>
class Connector;
class Vertex
{
public :
Vertex();
~Vertex();
Vertex(const Vertex& other);
Vertex& operator =(const Vertex& other);
std::unordered_set<Connector**> connection_set;
unsigned int get_state() const {return state;}
void set_state(unsigned int state) {this ->state = state;}
protected :
private :
unsigned int state;
};
#endif // VERTEX_H
Now, the issue here is that there is nothing that I can actually use inside of this code that would work as a hash function, as far as I can tell- the connection_set unordered_set can be empty, and state will be the same across too many vertex objects. So what can I do for this?
Last edited on Sep 13, 2014 at 10:07pm UTC
Sep 13, 2014 at 8:05pm UTC
If your vertices are fixed in memory you could use their addresses.
Sep 13, 2014 at 9:22pm UTC
1 2 3 4 5 6 7 8 9
namespace std {
template <>
class hash<Vertex*>{
public :
size_t operator ()(const Vertex &v ) const {
return hash<Vertex*>()(v);
}
};
}
Like that?
Also, just realized that even if I make each vertex have a default connector to null pointers, the end result is that the whole thing breaks- the hash function for vertex calls the hash for connector, which calls the hash for a pointer to vertex... yeah, I think that would just get out of hand very, very quickly. Memory location makes much more sense.
Last edited on Sep 13, 2014 at 9:30pm UTC
Sep 13, 2014 at 10:09pm UTC
Well, it would appear that I am now getting a particularly annoying error:
d:\codeblocks\mingw\bin\..\lib\gcc\mingw32\4.7.1\include\c++\bits\stl_function.h|210|undefined reference to `Vertex::operator ==(Vertex const &) const '|
in my attempt to overload operator== for Vertex. I have no idea how to fix this, or why it is even showing up. My code as of so far:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
#ifndef CONNECTOR_H
#define CONNECTOR_H
#include <memory>
#include <utility>
#include <unordered_set>
#include "Vertex.h"
class Connector
{
public :
Connector();
Connector(Vertex**,Vertex**);
~Connector();
Connector(const Connector& other);
Connector& operator =(const Connector& other);
const std::pair<Vertex**,Vertex**> vertex_pair;
unsigned int get_state() const {return state;}
void set_state(unsigned int state) {this ->state = state;}
protected :
private :
unsigned int state;
};
namespace std {
template <>
class hash<Connector>{
public :
size_t operator ()(const Connector &c ) const {
return hash<Vertex**>()(c.vertex_pair.first) ^ hash<Vertex**>()(c.vertex_pair.second);
}
};
}
#endif // CONNECTOR_H
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
#ifndef GRAPH_H
#define GRAPH_H
#include <unordered_map>
#include <unordered_set>
#include <memory>
#include "Connector.h"
#include "Vertex.h"
class Graph
{
public :
Graph();
~Graph();
Graph(const Graph& other);
Graph& operator =(const Graph& other);
void create_vertex();
void copy_vertex(Vertex&);
void create_connector(Vertex,Vertex);
void delete_connector(Connector);
void delete_vertex(Vertex);
protected :
private :
std::unordered_multimap<Vertex,Connector> graph_map;
std::unordered_set<Vertex> vertex_holder;
};
#endif // GRAPH_H
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
#ifndef VERTEX_H
#define VERTEX_H
#include <memory>
#include <utility>
#include <unordered_set>
class Connector;
class Vertex
{
public :
Vertex();
~Vertex();
Vertex(const Vertex& other);
Vertex& operator =(const Vertex& other);
inline bool operator ==(const Vertex&) const ;
std::unordered_set<Connector**> connection_set;
unsigned int get_state() const {return state;}
void set_state(unsigned int state) {this ->state = state;}
protected :
private :
std::pair<int ,int >coordinates;
unsigned int state;
};
namespace std {
template <>
class hash<Vertex>{
public :
size_t operator ()(const Vertex &v ) const {
return hash<Vertex>()(v);
}
};
}
#endif // VERTEX_H
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
#include "Connector.h"
Connector::Connector()
: vertex_pair(std::make_pair(nullptr ,nullptr ))
, state(0) {}
Connector::Connector(Vertex** v1,Vertex** v2)
: vertex_pair(std::make_pair(v1,v2))
, state(0)
{
}
Connector::~Connector()
{
if (vertex_pair.first == nullptr )
return ;
if (vertex_pair.second == nullptr )
return ;
auto * a = vertex_pair.first;
auto * b = vertex_pair.second;
for ( auto p : (*a)->connection_set)
if (*p == this )
(*a)->connection_set.erase(p);
for ( auto p : (*b)->connection_set)
if (*p == this )
(*b)->connection_set.erase(p);
}
Connector::Connector(const Connector& other)
: vertex_pair(other.vertex_pair)
, state(other.state) {}
Connector& Connector::operator =(const Connector& rhs)
{
if (this == &rhs) return *this ; // handle self assignment
this ->state = rhs.state;
return *this ;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
#include "Graph.h"
Graph::Graph()
{
//ctor
}
Graph::~Graph()
{
//dtor
}
Graph::Graph(const Graph& other)
{
//copy ctor
}
Graph& Graph::operator =(const Graph& rhs)
{
if (this == &rhs) return *this ; // handle self assignment
//assignment operator
return *this ;
}
void Graph::create_vertex()
{
Vertex * vert = new Vertex;
vertex_holder.emplace(*vert);
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
#include "Vertex.h"
Vertex::Vertex()
: state(0)
, coordinates(0,0)
{
//ctor
}
Vertex::~Vertex()
{
//dtor
}
Vertex::Vertex(const Vertex& other) :
state(other.state)
{
}
Vertex& Vertex::operator =(const Vertex& rhs)
{
if (this == &rhs) return *this ; // handle self assignment
this ->state = rhs.state;
return *this ;
}
inline bool Vertex::operator ==(const Vertex& rhs) const
{
if (this ->state == rhs.get_state())
if (this ->connection_set.size() == rhs.connection_set.size())
{
for (std::unordered_set<Connector**>::const_iterator i = this ->connection_set.begin(); i != this ->connection_set.end();i++)
{
if (rhs.connection_set.find(*i) == rhs.connection_set.end())
return false ;
return true ;
}
}
else
return false ;
else
return false ;
}
No, there is no main()- I have yet to get that far.
Last edited on Sep 13, 2014 at 10:41pm UTC
Sep 13, 2014 at 11:06pm UTC
The inline keyword implies internal linkage. The operator== defined in Vertex.cpp will not be usable outside of that file. Either get rid of the inline or move the definition to the header file. My vote would be for the former.
Sep 13, 2014 at 11:10pm UTC
Thanks! Go figure that it is always something little like that that keeps being the error in this code of a million pointers.
Topic archived. No new replies allowed.