Bug - std::bind problems with non const.

closed account (3qX21hU5)
So I am currently trying to debug some code in one of my projects. I'll list the code in question first and hopefully any relevant parts then go over the problem (If you need more code just ask).

Also here is the error code I am getting.
c:\users\brandon\documents\visual studio 2012\projects\sfml game\sfml game\command.h(34): error C3849: function-style call on an expression of type 'const std::_Bind<_Forced,_Ret,_Fun,_V0_t,_V1_t,_V2_t,_V3_t,_V4_t,_V5_t,<unnamed-symbol>>' would lose const and/or volatile qualifiers for all 2 available operator overloads
1>          with
1>          [
1>              _Forced=true,
1>              _Ret=void,
1>              _Fun=std::_Pmf_wrap<void (__thiscall Aircraft::* )(void),void,Aircraft,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil,std::_Nil>,
1>              _V0_t=std::_Ph<1> &,
1>              _V1_t=std::_Nil,
1>              _V2_t=std::_Nil,
1>              _V3_t=std::_Nil,
1>              _V4_t=std::_Nil,
1>              _V5_t=std::_Nil,
1>              <unnamed-symbol>=std::_Nil
1>          ]


Here is the whole Aircraft Header and Source files.
https://github.com/bjumbeck/SFML/blob/master/Aircraft.h
https://github.com/bjumbeck/SFML/blob/master/Aircraft.cpp



Setting a action for the fire/missile commands. Trying to assign the methods fire() and launchMissile() to their respective actions.

This is where the compiler error is triggered
1
2
actionBindings[Fire].action = derivedAction<Aircraft>(std::bind(&Aircraft::fire, _1));
actionBindings[LaunchMissile].action = derivedAction<Aircraft>(std::bind(&Aircraft::launchMissile, _1));


Here is how the commands are stored
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
struct Command
{
	typedef std::function<void(SceneNode&, sf::Time)> Action;

						Command();

	Action					action;
	unsigned int				category;
};

// Adapter so we don't need to downcast all the time.
template <typename GameObject, typename Function>
Command::Action derivedAction(Function fn)
{
	return [=] (SceneNode& node, sf::Time deltaTime)
	{
		// Check to make sure cast is safe
		assert(dynamic_cast<GameObject*>(&node) != nullptr);

		fn(static_cast<GameObject&>(node), deltaTime);
	};
}



And the fire and launchMissile methods
1
2
3
4
5
void Aircraft::fire()
{
	if (Table[airCraftType].fireInterval != sf::Time::Zero)
		isFiring = true;
}


1
2
3
4
5
6
7
8
void Aircraft::launchMissile()
{
	if (missileAmmo > 0)
	{
		isLaunchingMissile = true;
		--missileAmmo;
	}
}



Now I will admit I am very new to the <functional> header and this is the first project I have used it in so I am still getting used to using function and bind.

But from what I have read (http://msdn.microsoft.com/en-us/library/031k84se.aspx ) it seems like I need to have fire() and launchMissile be const methods which I guess I could do but would rather see if there is any other options available or if I am completely wrong in thinking that they need to be const (Most likely true because I have no idea what this error is coming from).

So basically could anyone explain what exactly is happening here and why I am getting this bug? I am have been digging for the past few hours and can't really comprehend anything yet so thought I would ask here. Also if you need to see any other code just let me know can paste it here or send you to my projects repo.

Thanks in advance.
Last edited on
Could you post the entire error message?
closed account (3qX21hU5)
That is all it gave me for a error message.

Have done a few tests just a minute ago also and it doesn't seem to be a problem with fire() and launchMissile() not being const because when I changed them to const I still get the same error so I am quite stumped now.
Last edited on
It seems to me that you've bound only the this parameter to your member functions, yet the lambda is passing two parameters to the functor.
1
2
3
4
5
6
7
8
9
10
template <typename GameObject, typename Function>
Command::Action derivedAction(Function fn)
{
    return [=] (SceneNode& node, sf::Time deltaTime) mutable
    {
        // Check to make sure cast is safe
        assert(dynamic_cast<GameObject*>(&node) != nullptr);
        fn(static_cast<GameObject&>(node), deltaTime);
    };
}


http://stackoverflow.com/questions/5501959/why-does-c0xs-lambda-require-mutable-keyword-for-capture-by-value-by-defau

[edit: Replaced the simplified code I experimented with actual (modified) code from the OP.]
Last edited on
closed account (3qX21hU5)
Ahh thank you very much for that cire seemed to fix the problem and plan on reading through the SO post in the morning to figure out exactly what went wrong (Though I think I got a good idea now).

Once again thank you and now can finally get some sleep and not be thinking about it all night ;p
Last edited on
Topic archived. No new replies allowed.