2

I am attempting to create an implementation of the A* algorithm on a 2D grid and have arrived stuck at the point where I am needing to create a set of a node's neighbours. Below are the structs I am using.

// Holds values for x and y locations on the grid
struct Coord {
    int x, y;
};

// holds data for each node required for A*
struct Node {
    int type; // used for defining if this node is a blocker, empty, start or end
    Coord location;
    int g = 0;
    int h = 0;
    int f = g + h;
    Node *parent_; // pointer to this node's parent

    std::string debugmessage;
};

The error appears when I create this function here:

// finds a node's neighbours for A*
std::set<Node> neighbours(Node& n_) {

    std::set<Node> neighbours_;
    Node temp = n_;

    int x = temp.location.x;
    int y = temp.location.y;

    // start at the location belonging to 'n_'
    for (y; y < HEIGHT; y++) {
        for (x; x < WIDTH; x++) {

            // east
            if (x < WIDTH - 1) {
                neighbours_.insert(astarArray[x + 1][y]);
            }
            // west
            if (x > 0) {
                neighbours_.insert(astarArray[x - 1][y]);
            }
            // south
            if (y < HEIGHT - 1) {
                neighbours_.insert(astarArray[x][y + 1]);
            }
            // north
            if (y > 0) {
                neighbours_.insert(astarArray[x][y -1]);
            }
        }
    }

    return neighbours_;
}

Thank you for your time.

3 Answers3

2

You cannot have a std::set of something without overloading operator< or defining your own custom comparator. A std::set is typically a red-black tree with the objects being the keys, and that requires being able to compare the keys.

So either you make an operator< for nodes or you can make a custom comparator. Info on the custom comparator here.

Gabriel
  • 829
  • 5
  • 12
1

std::set is an associative container that contains a sorted set of unique objects of type Key. Sorting is done using the key comparison function Compare.

source

You have to overload the operator< for your node.

Cristian Ionescu
  • 181
  • 3
  • 10
-1

Many constructors (of the std) need comparison operators to work.

You use std::set, which dont know how to compare two Node objects.

As said in http://en.cppreference.com/w/cpp/container/set

std::set is an associative container that contains a sorted set of unique objects of type Key. Sorting is done using the key comparison function Compare.

So you need to define comparison operator or give std::set a Compare functor as parameter.

The compiler tells you the first one missing: "<"

struct Node {
    friend bool operator< (const Node& _nLeft, const Node& _nRight);
    //friend not necessary since we use struct (full public)
    ...
};

bool operator< (const Node& _nLeft, const Node& _nRight)
{
    if (_nLeft.type < _nRight.type)
        return true;

    ...
    return false;
}
Sandburg
  • 757
  • 15
  • 28
  • Thanks for that, this is for an assignment that I am rushing to complete and I simply used std::set again because it worked in a different section of the code, where use of set was a requirement. Using std::list instead, also removed that nested for loop that was entirely unnecessary... –  Mar 15 '18 at 14:40