gpt4 book ai didi

c++ - 使用 boost::optional 制作可选的 std::function 参数

转载 作者:太空狗 更新时间:2023-10-29 21:34:51 24 4
gpt4 key购买 nike

我有一个方法需要四个可选的回调。我希望能够使用 lambda 作为回调,但由于这些回调是可选的并且需要默认值,我想我会使用 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;
});

No viable conversion from '(lambda at /Users/..../GameLevel.cpp:249:8)' to 'NullableEarlyCollisionCallback' (aka 'optional &, const shared_ptr &, cpArbiter *)> >')

但是,如果我明确地将 lambda 包装在 NullableEarlyCollisionCallback() 中,它会起作用:

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 转换为 optional<> 类型。我错过了什么?

这是使用 Xcode 9 beta3。

最佳答案

std::function 可从 nullptr_t 构造。如此构造,当转换为 bool 时,该值将为 false。如果它包含一个函数对象,则 true

文档:

http://en.cppreference.com/w/cpp/utility/functional/function/function

http://en.cppreference.com/w/cpp/utility/functional/function/operator_bool

演示:

#include <functional>

struct GameObjectRef {};
struct cpArbiter {};

struct cpCollisionType {};

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;

struct MyThing
{
EarlyCollisionCallback a_, b_;
LateCollisionCallback c_, d_;

virtual void addCollisionMonitor(cpCollisionType a, cpCollisionType b,
EarlyCollisionCallback onCollisionBegin = nullptr,
EarlyCollisionCallback onCollisionPreSolve = nullptr,
LateCollisionCallback onCollisionPostSolve = nullptr,
LateCollisionCallback onCollisionSeparate = nullptr)
{
a_ = std::move(onCollisionBegin);
b_ = std::move(onCollisionPreSolve);
c_ = std::move(onCollisionPostSolve);
d_ = std::move(onCollisionSeparate);
}

void call_callbacks(const GameObjectRef &a, const GameObjectRef &b, cpArbiter *arbiter)
{
if (a_) a_(a, b, arbiter);
if (b_) b_(a, b, arbiter);
if (c_) c_(a, b, arbiter);
if (d_) d_(a, b, arbiter);
}
};

int main()
{
MyThing m;
}

关于c++ - 使用 boost::optional 制作可选的 std::function 参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45123153/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com