Sign in to follow this  
Daggerbot

[C++] Lambda function strangeness

Recommended Posts

I have a function that takes a [tt]std::function<void ()>[/tt] argument to define what to do when i certain action occurs. The actions are usually only a single line of code, so I decided to try the lambda syntax for the first time. For some reason gcc wants me to capture [tt]this[/tt] just to call a static function. Why would this be necessary? Is it a bug in gcc? Here's the code:

[source]
m_main_menu.add('q', "Quit Game", []{State::current(nullptr);});
[/source]

[tt]State::current[/tt] is a static function that sets the current game state. Setting it to [tt]nullptr[/tt] causes the main loop to end. Why would [tt]this[/tt] need to be captured in order to call a static function? This isn't a major issue at all, but just a curiosity. Any help is appreciated.

Share this post


Link to post
Share on other sites
The capture shouldn't be necessary, assuming you don't have a name in the namespace that's identical to State.

Share this post


Link to post
Share on other sites
Here's the constructor:

[source]
MainMenu::MainMenu ()
: m_substate(MAIN), m_name_entry(20)
{
// m_main_menu
m_main_menu.add('c', "Continue saved game", []{});
m_main_menu.add('n', "Start new game", [this]{substate(CHAPTER_SELECTION);});
m_main_menu.add('q', "Quit game", [this]{State::current(nullptr);});
}
[/source]

And the State class:

[source]
class State
{
public:
virtual ~State ();

// Current state
static StatePtr current ();
static void current (const StatePtr &state);

// Events
virtual void draw () = 0;
virtual void receive (int c) = 0;
};
[/source]

Share this post


Link to post
Share on other sites
Here is a minimal example that follows the basic idea of that code:
[code]

#include <map>
#include <functional>

class State
{
public:
virtual ~State ();

// Current state
static State * current();
static void current(const State *state);

// Events
virtual void draw () = 0;
virtual void receive (int c) = 0;
};

enum ChapterEnum {
CHAPTER_SELECTION
};

class MainMenu : public State
{
MainMenu::MainMenu ()
{
// m_main_menu
menuItems.insert(std::make_pair('c', []{}));
menuItems.insert(std::make_pair('n', []{substate(CHAPTER_SELECTION);}));
menuItems.insert(std::make_pair('q', []{State::current(nullptr);}));
}

static State *substate(ChapterEnum);

std::map<char, std::function<void ()>> menuItems;
};

int main() {

}
[/code]
Hint: minimal examples are something we can actually compile. It should not include references to things that you haven't posted.

This produces the following warning:
[quote]
1>c:\programming\c++0x\help\help\help.cpp(29): warning C4573: the usage of 'State::current' requires the compiler to capture 'this' but the current default capture mode does not allow it
[/quote]
Googling the error code gave me [url="http://stackoverflow.com/questions/4940259/c0x-lambdas-require-capturing-this-to-call-static-member-function"]this[/url] and [url="http://stackoverflow.com/questions/7280673/what-are-lookup-rules-when-calling-function-from-lambda"]also this[/url], which both claim this is a compiler bug (as it appears to be).

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