Path finding function
// keep track of visited nodes so we don't visit them twice
std::vector&lt;node&gt; visited_nodes;
auto visited = [&amp;visited_nodes] (node n) {
    return std::find(visited_nodes.begin(), visited_nodes.end(), n) != visited_nodes.end();
};


Every time you have to check whether a point has been visited, this is going to scan over the entire list of visited_nodes. Better to do a std::set

// path is currently from end to start, so reverse it
std::copy(path.rbegin(), path.rend(), ret.second);


Rather then constructing the path and reversing it, you could construct the path backwards.

When it comes to constructing all of the child nodes, I think your approach is confusing. You'd be better of constructing a new node rather then reusing the node. As it is, its not clear what you are doing. That section of code is also repetitive. I'd do something like

int x_dir = {0, 0, 1, -1}
int y_dir = {1, -1, 0, 0}

for(int pos = 0; pos &lt; 4; pos++)
{
    node child = parent;
    child.first += x_dir[pos];
    child.second += y_dir[pos];
    ...
}


Other notes:

The use of map is going to O(log), if you use a multidimensional array to hold the information for each point you can do it in O(1) time.

Using pairs to hold co-ordinates is easy. However, I suggest that its better to have a point class with x and y members. I think it makes what is going on clearer. Additionally, the point class can encapsulate the neighboring cell logic.