I have a method which takes four optional callbacks. I want to be able to use lambdas as the callbacks, but I since these callbacks are optional and need a default value, I thought I'd use boost::optional.
Here's a direct copy-paste from my code:
typedef std::function<bool(const GameObjectRef &a, const GameObjectRef &b, cpArbiter *arbiter)> EarlyCollisionCallback;
typedef std::function<void(const GameObjectRef &a, const GameObjectRef &b, cpArbiter *arbiter)> LateCollisionCallback;
typedef boost::optional<EarlyCollisionCallback> NullableEarlyCollisionCallback;
typedef boost::optional<LateCollisionCallback> NullableLateCollisionCallback;
virtual void addCollisionMonitor(cpCollisionType a, cpCollisionType b,
NullableEarlyCollisionCallback onCollisionBegin = boost::none,
NullableEarlyCollisionCallback onCollisionPreSolve = boost::none,
NullableLateCollisionCallback onCollisionPostSolve = boost::none,
NullableLateCollisionCallback onCollisionSeparate = boost::none);
The idea is that later I could pass a lambda as callback for, say, the "preSolve" pass of the physics engine and ignore the other optional parameters. This may be bad design, I will likely write this differently. But the real question here is a c++ one. When I try to call this, I get compiler errors at the call site:
addCollisionMonitor(CollisionType::ENEMY, CollisionType::PLAYER,
//onCollisionBegin
[](const GameObjectRef &enemy, const GameObjectRef &player, cpArbiter *arb)->bool{
CI_LOG_D("Enemy: " << enemy->getName() << " contact player: " << player->getName());
return true;
});
No viable conversion from '(lambda at /Users/..../GameLevel.cpp:249:8)' to 'NullableEarlyCollisionCallback' (aka 'optional &, const shared_ptr &, cpArbiter *)> >')
However, if I explicitly wrap the lambda in NullableEarlyCollisionCallback() it works:
addCollisionMonitor(CollisionType::ENEMY, CollisionType::PLAYER,
//onCollisionBegin
NullableEarlyCollisionCallback([](const GameObjectRef &enemy, const GameObjectRef &player, cpArbiter *arb)->bool{
CI_LOG_D("Enemy: " << enemy->getName() << " contact player: " << player->getName());
return true;
}));
I'm curious why in this instance the compiler can't just convert the lambda to the optional<> type. What am I missing?
This is using Xcode 9 beta3.