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 : Sélectionner tout - Visualiser dans une fenêtre à part
 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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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

Merci.