http://asawicki.info/ Programming, graphics, games, media, C++, Windows, Internet and more... 


20:47
Sun
21
Oct 2012
C++ Lambdas  A Simple Explanation
Much can be said about theory behind lambda expressions, but lambdas in C++  this new feature of C++11 supported by Visual C++ 2010, 2012, as well as other new compilers  can be explained very simply by following example. Today I wanted to write code that would sort a vector of pointers to entities in my 3D scene by distance from the camera, to ensure correct rendering of translucent objects.
std::vector<CEntity*> entitiesToRender;
vec3 cameraEyePos;
vec3 cameraForwardDir;
Vector in world space pointing forward from the camera  towards its positive Z axis  can be extracted from 3rd column of the view matrix. Dot product between this vector and a vector from camera position to object position gives length of the projection of one vector onto the other, which is the distance from the camera. But that's not the point here.
If you use STL, you know it's convenient to sort a vector using std::sort algorithm. Except if the contained type does not have operator< or you don't want it to be used (like here, as it would just compare pointers), you have to write a functor to compare elements. Lambda simplifies this task:
std::sort(
entitiesToRender.begin(),
entitiesToRender.end(),
[=](CEntity* lhs, CEntity* rhs)
{
return
dot(lhs>GetPosition()  cameraEyePos, cameraForwardDir) >
dot(rhs>GetPosition()  cameraEyePos, cameraForwardDir);
});
This code is equivalent to the traditional, more verbose version using functor:
class CompareFunctor
{
public:
CompareFunctor(const vec3& cameraEyePos, const vec3& cameraForwardDir) :
m_CameraEyePos(cameraEyePos),
m_CameraForwardDir(cameraForwardDir)
{
}
bool operator()(CEntity* lhs, CEntity* rhs) const
{
return
dot(lhs>GetPosition()  m_CameraEyePos, m_CameraForwardDir) >
dot(rhs>GetPosition()  m_CameraEyePos, m_CameraForwardDir);
}
private:
vec3 m_CameraEyePos;
vec3 m_CameraForwardDir;
};
std::sort(
entitiesToRender.begin(),
entitiesToRender.end(),
CompareFunctor(cameraEyePos, cameraForwardDir));
Parameters of lambda inside () are data passed to every call, like parameters of operator() in the functor. Inside [] we can specify what parameters are captured from the current context (local variables), which is equivalent to storing them as member variables inside the functor. [=] means capturing all necessary parameters by value, which are cameraEyePos and cameraForwardDir in this case. [&] would remember them by reference.
Comments (3)  Tags: c++  Author: Adam Sawicki  Share
[Stat] [Admin] [STAT NO AD] [pub] [Mirror]  Copyright © 20042017 Adam Sawicki 