我有一个方法,需要四个可选的回调。我希望能够使用lambdas作为回调,但是因为这些回调是可选的并且需要一个默认值,我想我会使用boost :: optional。
以下是我的代码中的直接复制粘贴:
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);
我的想法是,稍后我可以将lambda作为回调传递给物理引擎的“preSolve”传递,并忽略其他可选参数。这可能是糟糕的设计,我可能会以不同的方式写出来。但这里真正的问题是c ++问题。当我尝试调用时,我在调用站点遇到编译器错误:
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;
});
没有可行的转换从'(lambda at /Users/..../GameLevel.cpp:249:8)'到'NullableEarlyCollisionCallback'(又名'可选&amp;,const shared_ptr&amp;,cpArbiter *)&gt; &GT;')
但是,如果我在NullableEarlyCollisionCallback()中明确地包装lambda它可以工作:
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;
}));
我很好奇为什么在这种情况下编译器不能只将lambda转换为可选的&lt;&gt;类型。我错过了什么?
这是使用Xcode 9 beta3。
答案 0 :(得分:2)
m2
可以std::function
构建。如此构造,当转换为nullptr_t
时,该值将为bool
。如果它包含一个函数对象,那么false
。
文档:
http://en.cppreference.com/w/cpp/utility/functional/function/function
http://en.cppreference.com/w/cpp/utility/functional/function/operator_bool
示范:
true