[C++] Lambda function strangeness

Started by
3 comments, last by rip-off 12 years, 1 month ago
I have a function that takes a std::function<void ()> 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 this 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]

State::current is a static function that sets the current game state. Setting it to nullptr causes the main loop to end. Why would this 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.
Advertisement
The capture shouldn't be necessary, assuming you don't have a name in the namespace that's identical to State.

In time the project grows, the ignorance of its devs it shows, with many a convoluted function, it plunges into deep compunction, the price of failure is high, Washu's mirth is nigh.

Can you show us the code? Or a minimal equivalent example that has the same behaviour.
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]
Here is a minimal example that follows the basic idea of that 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() {

}

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:

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 this and also this, which both claim this is a compiler bug (as it appears to be).

This topic is closed to new replies.

Advertisement