Jump to content



[C++] Lambda function strangeness

  • You cannot reply to this topic
4 replies to this topic

#1 Daggerbot   Members   -  Reputation: 127

Like
0Likes
Like

Posted 18 February 2012 - 02:15 PM

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:

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

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.

Ad:

#2 Washu   Senior Moderators   -  Reputation: 2448

Like
0Likes
Like

Posted 18 February 2012 - 04:15 PM

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.
ScapeCode - Blog | SlimDX

#3 rip-off   Moderators   -  Reputation: 2482

Like
0Likes
Like

Posted 18 February 2012 - 07:17 PM

Can you show us the code? Or a minimal equivalent example that has the same behaviour.

#4 Daggerbot   Members   -  Reputation: 127

Like
0Likes
Like

Posted 19 February 2012 - 12:34 PM

Here's the constructor:

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);});
}

And the State class:

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;
};


#5 rip-off   Moderators   -  Reputation: 2482

Like
0Likes
Like

Posted 19 February 2012 - 06:00 PM

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:

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






We are working on generating results for this topic
PARTNERS