如何使函数中的引用参数可选(可选缓冲区)

发布于 2024-11-16 06:22:09 字数 321 浏览 2 评论 0原文

因此,我正在制作一个函数来检测两个精灵之间的碰撞,并希望添加两个缓冲区作为可选参数,以填充每个对象碰撞的侧面角度。

然而,这意味着两个 buff 参数必须是引用,并且每当调用函数时都必须存在,并且我不知道有任何方法可以进行默认引用。我该如何做到这一点?

这是实际功能:

bool CheckCollision(T* obj1, T* obj2, float& CollBuff1= new float, float& CollBuff2= new float);

我尝试使用“new”进行默认设置,但它不起作用。

So I'm making a function that detects collisions between two sprites, and would like to add two buffers as optional parameters to be filled with the angle of the sides of each objects collision.

However this means the two buff parameters must be references, and must be there whenever the function is called, and I am not aware of any way to make a default reference. How can I do this?

Here's the actual function:

bool CheckCollision(T* obj1, T* obj2, float& CollBuff1= new float, float& CollBuff2= new float);

I tried to make a default with 'new' but it didn't work.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

我为君王 2024-11-23 06:22:09

您可以重载该函数。只需定义第二个包装函数,如下所示:

bool CheckCollision(T *obj1, T *obj2)
{
    float dummy1, dummy2;
    return CheckCollision(obj1, obj2, dummy1, dummy2);
}

如果您愿意,还可以在仅提供一个浮点数时定义第二个包装函数。

You can overload the function. Just define a second wrapper function like so:

bool CheckCollision(T *obj1, T *obj2)
{
    float dummy1, dummy2;
    return CheckCollision(obj1, obj2, dummy1, dummy2);
}

And define a second one for when only one float is provided, if you like.

罪歌 2024-11-23 06:22:09

使用 Boost.Optional,没有指针,也没有样板重载:

bool CheckCollision(
    T* obj1, T* obj2,
    boost::optional<float&> CollBuff1 = boost::optional<float&>(),
    boost::optional<float&> CollBuff2 = boost::optional<float&>()
);

您可以通过执行 if (CollBuff1) 测试是否获得了参数,然后使用 CollBuff1.get() 访问引用(显然,另一个也以同样的方式)。

With Boost.Optional, no pointers and no boilerplate overloading:

bool CheckCollision(
    T* obj1, T* obj2,
    boost::optional<float&> CollBuff1 = boost::optional<float&>(),
    boost::optional<float&> CollBuff2 = boost::optional<float&>()
);

You can test whether you've got the argument by doing if (CollBuff1), and then access the reference with CollBuff1.get() (and the other one the same way, obviously).

追风人 2024-11-23 06:22:09

另一种(而且非常丑陋)的方法是这样的:

#include <memory>

void test(int a, int& b = *std::auto_ptr<int>(new int())) {
     // ...
}

或者在你的情况下

#include <memory>

bool CheckCollision(T* obj1, T* obj2,
    float& CollBuff1= *std::auto_ptr<float>(new float()),
    float& CollBuff2= *std::auto_ptr<float>(new float()));

An alternative (and very ugly) way to do this would be this:

#include <memory>

void test(int a, int& b = *std::auto_ptr<int>(new int())) {
     // ...
}

or in your case

#include <memory>

bool CheckCollision(T* obj1, T* obj2,
    float& CollBuff1= *std::auto_ptr<float>(new float()),
    float& CollBuff2= *std::auto_ptr<float>(new float()));
猫性小仙女 2024-11-23 06:22:09

@James McNellis 的一个现已删除(为什么?)的答案指出了正确的解决方案:你不这样做。

为此使用指针,因为这些缓冲区显然是外参数(即,它们用于“返回”附加值)并相应地调用它:

bool CheckCollision(T* obj1, T* obj2, float* ColBuf1 = 0, float* ColBuf2 = 0){
  // your code...
  // ...
  // test before assigning:
  if(ColBuf1 != 0)
    *ColBuf1 = /*whatever you have*/;
  // same with ColBuf2
}

float ColBuf1, ColBuf2;
CheckCollision(SomeObjPtr, AnotherObjPtr, &ColBuf1, &ColBuf2);

或者,更好的是,重载它:

bool CheckCollision(T* obj1, T* obj2);
bool CheckCollision(T* obj1, T* obj2, float* ColBuf1, float* ColBuf2);

尽管我仍然使用指针来指示这些缓冲区将被填满。

A now deleted (why?) answer from @James McNellis points out the correct solution: You don't.

Use pointers for this, as those buffers are obviously out-parameters (i.e., they're used to "return" additional values) and call it accordingly:

bool CheckCollision(T* obj1, T* obj2, float* ColBuf1 = 0, float* ColBuf2 = 0){
  // your code...
  // ...
  // test before assigning:
  if(ColBuf1 != 0)
    *ColBuf1 = /*whatever you have*/;
  // same with ColBuf2
}

float ColBuf1, ColBuf2;
CheckCollision(SomeObjPtr, AnotherObjPtr, &ColBuf1, &ColBuf2);

Or, even better, overload it:

bool CheckCollision(T* obj1, T* obj2);
bool CheckCollision(T* obj1, T* obj2, float* ColBuf1, float* ColBuf2);

Though I'd still use pointers to indicate that those buffers are going to be filled.

辞慾 2024-11-23 06:22:09

尝试为引用参数定义默认值时遇到的基本问题是非常量引用不能绑定到临时对象或文字。

void foo(float &f = 1.0f) {} // doesn't compile
void foo(const float &f = 1) {} // OK

事实上这是合法的:

void foo(float &f = *(new float(1))) {}

但这是不可取的。函数中的代码无法判断它是否是使用默认参数调用的,因此您为自己创建了一个相当不愉快的资源处理问题:谁将删除该浮动,如果调用者确实传递了某些内容,该代码会做什么? bdonlan 的过载更可取。

The basic problem you have in trying to define a default value for a reference parameter is that a non-const reference can't be bound to a temporary object or a literal.

void foo(float &f = 1.0f) {} // doesn't compile
void foo(const float &f = 1) {} // OK

In fact this is legal:

void foo(float &f = *(new float(1))) {}

But it's rather inadvisable. The code in the function can't tell whether it was called with the default parameter or not, so you've created a rather unpleasant resource-handling problem for yourself: who is going to delete that float, and what will that code do in the case where the caller did pass something? bdonlan's overload is preferable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文