使用boost :: optional来生成可选的std :: function参数

时间:2017-07-15 22:11:25

标签: c++ c++11 boost lambda

我有一个方法,需要四个可选的回调。我希望能够使用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。

1 个答案:

答案 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