[Erreur compilation] Undefined reference
Bonsoir à tous.
Je bloque sur une erreur de compilation depuis 1 heure et pas moyen de savoir d'où elle sort. C'est la fameuse undefined reference, en théorie je sais ce que c'est (souvent dû à une déclaration sans implémentation). Je met le code en "vrac" réparti dans 5 fichiers et compilé avec la commande :
Code:
g++ grid_graph.cpp maze.cpp test.cpp
En résumé, c'est une classe "classique" maze qui hérite d'une classe template grid_graph.
Code de test.
Code:
1 2 3 4 5 6 7
| #include "maze.hpp"
int main(int argc, char* argv[])
{
maze m = maze(5,5);
return 0;
} |
Classe Maze.
Code:
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 MAZE
#define MAZE
#include "grid_graph.hpp"
#include <utility>
#include <cmath>
struct maze_vertex
{
char walls;
int altitude;
};
class maze : public grid_graph<maze_vertex>
{
public:
maze(std::size_t columns, std::size_t lines);
void wall(std::size_t x, std::size_t y, direction d);
void altitude(std::size_t x, std::size_t y, std::size_t altitude);
std::size_t distance(vertex_type &source, vertex_type &target);
};
#endif |
Code:
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
| #include "maze.hpp"
maze::maze(std::size_t x_max, std::size_t y_max)
: grid_graph(x_max, y_max)
{
}
void maze::wall(std::size_t x, std::size_t y, direction d)
{
std::pair<std::size_t, std::size_t> p = std::make_pair<std::size_t, std::size_t>(x,y);
vertex_value(p).walls ^= (1 << d);
}
void maze::altitude(std::size_t x, std::size_t y, std::size_t altitude)
{
std::pair<std::size_t, std::size_t> p = std::make_pair<std::size_t, std::size_t>(x,y);
vertex_value(p).altitude = altitude;
}
std::size_t maze::distance(vertex_type &source, vertex_type &target)
{
/* Euclidean distance :
n is the number of dimension.
n
distance(P,Q) = Square root ( SUM ( Pi - Qi) )
i=0 */
std::size_t index_source = index(source);
std::size_t index_target = index(target);
std::size_t diff = std::abs(index_source - index_target);
if(diff == 1 || diff == x_max)
{
return std::sqrt((source.first - target.first) +
(source.second - target.second) +
(graph[index_source].altitude - graph[index_target].altitude));
}
return INFINITE_VALUE;
} |
Classe grid_graph.
Code:
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
| #ifndef GRID_GRAPH
#define GRID_GRAPH
#include <vector>
#include <limits>
#include <stdexcept>
#include <cmath>
#include <utility>
template <typename value_type>
class grid_graph
{
public:
typedef std::pair<std::size_t, std::size_t> vertex_type;
typedef typename std::vector<value_type>::iterator value_iterator;
typedef enum {TOP, RIGHT, BOTTOM, LEFT} direction;
static const std::size_t INFINITE_VALUE;
static const std::size_t UNDEFINED;
protected:
struct end_vertex_iterator_tag {};
struct begin_vertex_iterator_tag {};
std::size_t index(vertex_type &vertex);
std::vector<value_type> graph;
const std::size_t x_max;
const std::size_t y_max;
public:
struct vertex_iterator
{
private:
std::size_t index;
const std::size_t x_max;
const std::size_t y_max;
vertex_iterator(const std::size_t x_max, const std::size_t y_max, begin_vertex_iterator_tag) : x_max(x_max), y_max(y_max), index(0){};
vertex_iterator(const std::size_t x_max, const std::size_t y_max, end_vertex_iterator_tag) : x_max(x_max), y_max(y_max), index(x_max*y_max){};
public:
bool operator==(const vertex_iterator &v) const
{
return index == v.index;
}
bool operator!=(const vertex_iterator &v) const
{
return index != v.index;
}
void operator++()
{
index += (index < x_max*y_max);
}
void operator--()
{
index -= (index > 0);
}
grid_graph::vertex_type operator*()
{
if(index < x_max*y_max)
return std::make_pair<std::size_t, std::size_t>(index % y_max, index % x_max);
}
};
grid_graph(std::size_t columns, std::size_t lines);
vertex_iterator vertex_begin();
vertex_iterator vertex_end();
value_iterator value_begin();
value_iterator value_end();
std::size_t vertex_size();
value_type& vertex_value(vertex_type &vertex);
template<typename neighbor_container>
void neighbor(vertex_type &vertex, neighbor_container &neighbors);
vertex_type next(vertex_type &vertex, direction x) throw();
std::size_t distance(vertex_type &source, vertex_type &target);
std::size_t unique_id(vertex_type &vertex);
};
#endif |
Code:
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
| #include "grid_graph.hpp"
template <typename value_type>
const std::size_t grid_graph<value_type>::INFINITE_VALUE = std::numeric_limits<std::size_t>::max();
template <typename value_type>
const std::size_t grid_graph<value_type>::UNDEFINED = std::numeric_limits<std::size_t>::max();
template <typename value_type>
grid_graph<value_type>::grid_graph(std::size_t x_maxs, std::size_t y_maxs)
{
x_max = x_maxs;
y_max = y_maxs;
graph = std::vector<value_type>();
graph.resize(x_max * y_max);
}
template <typename value_type>
std::size_t grid_graph<value_type>::vertex_size()
{
return graph.size();
}
template <typename value_type>
std::size_t grid_graph<value_type>::unique_id(vertex_type &vertex)
{
return index(vertex);
}
template <typename value_type>
typename grid_graph<value_type>::value_iterator grid_graph<value_type>::value_begin()
{
return graph.begin();
}
template <typename value_type>
typename grid_graph<value_type>::value_iterator grid_graph<value_type>::value_end()
{
return graph.end();
}
template <typename value_type>
typename grid_graph<value_type>::vertex_iterator grid_graph<value_type>::vertex_begin()
{
return vertex_iterator(x_max, y_max, begin_vertex_iterator_tag());
}
template <typename value_type>
typename grid_graph<value_type>::vertex_iterator grid_graph<value_type>::vertex_end()
{
return vertex_iterator(x_max, y_max, end_vertex_iterator_tag());
}
template <typename value_type>
std::size_t grid_graph<value_type>::index(vertex_type &vertex)
{
return vertex.first + vertex.second * x_max;
}
template <typename value_type>
value_type& grid_graph<value_type>::vertex_value(vertex_type &vertex)
{
return graph[index(vertex)];
}
template <typename value_type>
template <typename neighbor_container>
void grid_graph<value_type>::neighbor(vertex_type &vertex, neighbor_container &neighbors)
{
for(int d=0; d < 4; ++d)
try{
neighbors.push_back(next(vertex, d));
}catch(std::out_of_range &oor){}
}
template <typename value_type>
typename grid_graph<value_type>::vertex_type grid_graph<value_type>::next(vertex_type &vertex, direction x) throw()
{
std::size_t vertex_index = index(vertex);
switch(x)
{
case TOP:
return graph[vertex_index - x_max];
case RIGHT:
if(vertex_index % x_max == (vertex_index + 1) % y_max)
return graph[vertex_index + 1];
else throw new std::out_of_range("");
case BOTTOM:
return graph[vertex_index + x_max];
case LEFT:
if(vertex_index % x_max == (vertex_index - 1) % y_max)
return graph[vertex_index - 1];
else throw new std::out_of_range("");
default:
throw new std::out_of_range("");
}
}
template <typename value_type>
std::size_t grid_graph<value_type>::distance(vertex_type &source, vertex_type &target)
{
std::size_t diff = std::abs(index(source) - index(target));
return (diff == 1 || diff == x_max) ? 1 : INFINITE_VALUE;
} |
Désolé pour le paté de code mais bon je suppose que vous avez déjà vu plus gros :mrgreen:
Merci.