Ok I'm in a strange situation where I want to define a function within a function. I can of course define the function outside of the other function but this will just pollute a namespace. Since I a) have to define a separate function and b) it will only be called from one other function, it would be really nice to be able to declare and define the function inside that other function.
Since this isn't allowed, is there some alternative? The basic application is that I want to count the number of "cell" class instances that are touching "Cell1" (or touching instances that are touching cell1, etc.).
I'm pretty sure what you're trying to do is simply impossible. Perhaps a little more detail involving the problem and what code the function would be running would help us suggest an alternate approach?
If you're only calling the function once, there is hardly a point to having the function at all; just write the function's code out in place. If you're calling it several times, maybe some kind of loop would be useful.
Zhuge: I have to declare a function because it's a recursive call.
A simple, analogous example is if we have a vector of "Cell" objects, and we want to know which cells belong to one "colony" (ie all cells indirectly touch one another). I don't know of any of efficiently working this out without creating ungodly piles of vectors that need to be created, resized and destroyed N^2 number of times.
The below example uses the World::Colonies() to build a vector of cell vectors (called colonies). Each colony contains only cells that are touching.
typedef std::vector<Cell*> Colony; // a colony is a vector of cells
// return a vector of colonies
std::vector<Colony> const& World::Colonies() const
{
std::vector<Colony> colony_vector;
std::vector<Cell*> unallocated_cells = cell_register; // cells which do not yet have a colony to which they belong
while (unallocated_cells.size() > 0)
{
std::vector<Cell*> allocated_cells; // build the colony
PopulateColonyVector(unallocated_cells,allocated_cells,unallocated_cells.begin()); // fill the vector with a colony
Colony& new_colony = allocated_cells; // for clarity
colony_vector.push_back(allocated_cells); // add the colony to the colony vector
}
return colony_vector;
}
// define a colony of cells based on an input vector (removes the colony members from that vector as well)
void World::PopulateColonyVector(std::vector<Cell*>& unallocated_cells,std::vector<Cell*>& allocated_cells, std::vector<Cell*>::iterator it_unallocated_cell) const
{
auto p_cell = *it_unallocated_cell;
allocated_cells.push_back(p_cell); // add the cell pointer to the allocated_cells
unallocated_cells.erase(it_unallocated_cell); // remove the cell from the unallocated_cells vector
// (at this point it_cell is invalid)
// build a list of cells with which the current cell collides, but which are not yet allocated
std::vector<Cell*> unallocated_contact_cells;
for (auto it = unallocated_cells.begin(); it != unallocated_cells.end(); it++)
{
if (Contact(*it,p_cell)) // The World->Contact() method returns true if the two cell object pointers belong to cells which are touching one another
{
unallocated_contact_cells.push_back(*it); // it to the list of contact cells
if ((it = unallocated_cells.erase(it)) == unallocated_cells.end())
break; // break if that was the last element
}
}
// loop through each contact cell and recourse this function
for (auto p_unallocated_contact_cell : unallocated_contact_cells)
{
auto it_unallocated_contact_cell = find(unallocated_cells.begin(),unallocated_cells.end(),p_unallocated_contact_cell);
PopulateColonyVector(unallocated_cells,allocated_cells,it_unallocated_contact_cell);
}
}
If you know of a cleaner and not obtrusively resource intense method of achieving this please let me know, it's a problem I've often struggled with.