Jump to content
  • Advertisement
Sign in to follow this  
ankhd

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

This topic is 1071 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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
Advertisement

As for performance, the compiler is pretty good at inlining lambdas when appropriate, especially when they don't capture anything...

Share this post


Link to post
Share on other sites

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

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
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
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!