Sign in to follow this  
ankhd

What is This doing A Function With a defined function inside it.

Recommended Posts

ankhd    2304

Hey all.

 

While googling I found some code like this.

 

void SomeFunction()

{

      auto check = [&](int v1, int v2)-> int

    {

            //do stuff say add the 2 values

          return v1 + v2;

     };

 

//used say in a ???

int rt = check(34, 8);

 

}

 

Is this a What??? pointer to a defined function.

 

and is it wise to do things like this or does it have a impact on code speed or any other overhead.

 

Because after seeing it I found a place I could use it which would allow me to keep it all in one function.

 

Any input would be good thank.

 

What I want to use it for is I have a function FindFreeCell and it has a std::list I use as a ordered list and may addToList could be setout like above.

Share this post


Link to post
Share on other sites
WozNZ    2010

As others have said its a lambda. The example you gave is a bit pointless and does not really show their benefit though.

 

They really come into their own when closures come into play, this is where they capture values from outside the scope of the lambda. When they do this they can be thought of as a class with one method, the lambda signature, and private data.

 

The following is C# but much the same

 

This function when called returns a function that takes void and returns int. The resulting function captures nextId and holds it while something references the returned function.

 

public Func<int> NextIdFactory()

{

    int nextId = 1;

    return () => nextId++;

}

 

Here it is being used. The first call to the factory creates a function that starts at id 1 and increments each call. The second call to the factory created a new version so starts at 1 again

 

public void DoSomeWork()

{

    var getNextId = NextIdFactory();

 

    var idA = getNextId(); // = 1

    var idB = getNextId(); // = 2

 
    getNextId = NextIdFactory(); // Reset to new generator
 
    var idC = getNextId(); // = 1 

}

 

You can pass a reference around to the lambda like any other piece of data. They have some powerful uses when you get the hang of them from partial application, caching, memoisation. They are normally associated with a more functional style than OO but are gaining traction in the OO world.

Share this post


Link to post
Share on other sites
ankhd    2304

Ok Thanks.

Going by this here.

 

this is how I had my function before reading here.

.

auto AddToPriorityQueue = [&](std::list<cCell *> &Priorityqueue, cCell *cell )
{}

and after reading I changed it to this

.

cCell *cGridManager::GetNearestFreeCell(D3DXVECTOR3 &startlocation, float mindistance, float maxdistance)
{
	std::list<cCell *> Priorityqueue;//ordered list

	
	//define a function for adding to the above list
    auto AddToPriorityQueue = [&Priorityqueue, &mindistance]( cCell *cell )
    { 
		//if empty list 
		if(Priorityqueue.empty())
		{
			Priorityqueue.push_back(cell);
			return;//done
		}


		std::list<cCell *>::iterator it;
		for(it = Priorityqueue.begin(); it == Priorityqueue.end(); it++)
		{
			cCell *currentcell = (*it);
		
			D3DXVECTOR3 target = cell->Centre - currentcell->Centre;

			float distance = D3DXVec3Length(&target);
			if(distance > mindistance)
			{
				//incert here
				Priorityqueue.insert(it,cell);
				return;//done
			}

		}//end all list Items
		
		//if we get here just add it to the end
		Priorityqueue.push_back(cell);

	};//end AddToPriorityQueue


this is the important parts.

 auto AddToPriorityQueue = [&](std::list<cCell *> &Priorityqueue, cCell *cell ) this to

 

this

 auto AddToPriorityQueue = [&Priorityqueue, &mindistance]( cCell *cell )

 

The later one is the optimum solution, I did also have to do the same with mindistance when I put the queue in the [] the function no longer recognize the variable mindistance.

Is it sharing the queue and recognized vars.

 

Does it matter which way it goes.

Share this post


Link to post
Share on other sites
SmkViper    5396
I find them really useful when working with algorithms that take templated callable objects:

struct Person
{
  std::string Name;
  int Age;
}

void OutputCountOfTeens(const std::vector<Person> aInputData)
{
  const auto teenagerCount = std::count_if(aInputData.begin(), aInputData.end(), [] (const Person& aPerson)
    {
      return (aPerson.Age >= 13) && (aPerson.Age <= 19);
    }
  );
  
  std::cout << "We were given " << teenagerCount << " teens.\n";
}
Note that I can define the predicate in-line with the function call without having to make a whole functor class or separate function if I only need it one place, which kind of lets me treat several algorithms as fancy for loops.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this