How to make a reference parameter in a function optional (optional buffer)
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 c开发者_如何学运维an 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.
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.
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).
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()));
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.
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.
精彩评论