Path finding function Could this be made more efficient, and/or simpler?  It's a path-finding function.  It seems to work, but do you see any potential cases where it could fail?

// Searches for a path from [start] to [end].
// Predicate [passable] should take an std::pair&lt;int,int&gt; and return true if the node is passable.
// Nodes in path are stored in [out].
// Return value is a pair.  With first being a bool to indicate if a path was found,
// and second an iterator for the end of the path
template&lt;typename OutputIterator, typename PassablePR&gt;
std::pair&lt;bool, OutputIterator&gt; ShortestPath(std::pair&lt;int,int&gt; start, std::pair&lt;int,int&gt; end, PassablePR passable, OutputIterator out)
{
    typedef std::pair&lt;int,int&gt; node;

    std::pair&lt;bool, OutputIterator&gt; ret(false, out);

    // queue of nodes expanding out from the starting point
    std::queue&lt;node&gt; q;

    // 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();
    };

    // link child nodes to parents
    std::map&lt;node,node&gt; path_tree;

    q.push(start);
    while(q.empty() == false)
    {
        auto parent = q.front();
        if(passable(parent) &amp;&amp; !visited(parent))
        {
            visited_nodes.push_back(parent);

            if(parent == end)
            {
                ret.first = true;
                std::vector&lt;std::pair&lt;int,int&gt;&gt; path;
                auto i = path_tree.find(parent);
                while(i != path_tree.end())
                {
                    path.push_back(i-&gt;first);
                    parent = i-&gt;second;
                    path_tree.erase(i);
                    i = path_tree.find(parent);
                }

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

                return ret;
            }

            auto child(parent);

            // node to the left         
            --child.first;
            q.push(child);          
            if(path_tree.find(child) == path_tree.end())
                path_tree[child] = parent;

            // right
            child.first += 2;
            q.push(child);
            if(path_tree.find(child) == path_tree.end())
                path_tree[child] = parent;

            // above
            --child.first;
            --child.second;
            q.push(child);
            if(path_tree.find(child) == path_tree.end())
                path_tree[child] = parent;

            // and below
            child.second += 2;
            q.push(child);
            if(path_tree.find(child) == path_tree.end())
                path_tree[child] = parent;
        }
        q.pop();
    }
    return ret;
}


Testing it out:

int main()
{
    int grid[5][5] =
    { { 0, 1, 0, 0, 0 },
      { 0, 0, 0, 1, 0 },
      { 0, 1, 0, 1, 0 },
      { 0, 1, 0, 1, 0 },
      { 0, 0, 0, 1, 0 } };

    std::vector&lt;std::pair&lt;int,int&gt;&gt; path;

    auto ret = ShortestPath(std::pair&lt;int,int&gt;(0,0), std::pair&lt;int,int&gt;(4,4),
        [&amp;grid] (std::pair&lt;int,int&gt; n) -&gt; bool {
            if(ben::WithinBoundsInclusive(std::pair&lt;int,int&gt;(0,0), std::pair&lt;int,int&gt;(4,4), n) == false)
                return false;
            return grid[n.first][n.second] == 0;
        },
        std::back_inserter(path));

    if(ret.first)
    {
        std::cout &lt;&lt; "Path found\n";

        std::for_each(path.begin(), path.end(),
            [](std::pair&lt;int,int&gt; n) {
                std::cout &lt;&lt; '(' &lt;&lt; n.first &lt;&lt; ',' &lt;&lt; n.second &lt;&lt; ")\n";
            });
    }
    else
        std::cout &lt;&lt; "Path not found\n";
}
// 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.