return a float array in a function

Started by
17 comments, last by cozzie 10 years, 9 months ago
Note that C++ has a standard container to encapsulate fixed size arrays: std::array. Here you could use a std::array<float, 3>. Of course, std::array is a relatively recent addition to C++, so not all compilers will have it. If yours doesn't you can use boost::array instead. While there is no implicit conversion from a std::array<float, 3> to float *, you can use .data() on a non-const rvalue. Ex:

std::array<float, 3> foo();
void bar(float *);

int main(int, char **) {
  bar(foo().data());
}
Advertisement


You could make a conversion operator...

... but don't. There is a reason why the standard committed opted for std::string::c_str() rather than making an implicit conversion to C string.

Consider what that code allows:

Vec3 vec = /* ... */;
 
if(vec)
{
   // ...
}

The intent here was probably to perform a more interesting condition, but the implicit conversion allows this code to compile.

You might say that is unlikely, and you are probably right. What about this example, where the programmer probably meant to apply a function such as lengthSqrd() to each vector:

Vec3 a = /* ... */;
Vec3 b = /* ... */;
    
if(a < b)
{
    // ...
}

@rip-off

Thank you for pointing out possible problems with this.

One way i could see to avoid that is to make:

struct Vec3
{
private:

    operator bool ()
    {
        return false;
    }

public:
...

and have compile time error if such thing happen by accident.

Do you see any problem with this?

I still think a named function, such as toArray() / asArray(), would be better.

You'd have to add "operator bool() const" too, to avoid the same problem with const objects. You could still run into this problem inside private or friend functions, though this is unlikely to be a scenario for a (formerly) simple vector class. You could however omit the implementation, thus getting a linker error if it is erroneously used even by a privileged function. Finally, you have to explain/justify these bizarre function stubs to your team, and write a suitably menacing comment so no-one accidentally deletes the apparently unused code...

Thanks all.

I think I've a found a good balance without taking risk and now did it like this:


// private members

D3DXVECTOR3 mPosition;
float *mPosF;

// public member function prototype
float* GetPositionF() const;

// the member function implementation
float* CD3dcam::GetPositionF() const
{
	return mPosF;
}

// in constructor
mPosF = new float[3];

// in destructor
delete[] mPosF;

// the call where I use the array
if(FAILED(pD3dscene->mShaders[0].mEffect->SetFloatArray(pD3dscene->mShaders[0].mHCameraPos, (float*)pCam->GetPositionF(), 3))) return false;	// NOT SHARED YET!!!! MIND YOU!!

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

D3DXVECTOR3 already have conversion/cast operator so you could just pass that:


const D3DXVECTOR3& CD3dcam::GetPosition() const
{
    return mPosition;
}
...
if(FAILED(pD3dscene->mShaders[0].mEffect->SetFloatArray(pD3dscene->mShaders[0].mHCameraPos, pCam->GetPosition(), 3)) return false;


Thanks all.

I think I've a found a good balance without taking risk and now did it like this:
[...]

Your use of new and delete[] seems suspicious. Why do you want to allocate a separate piece of memory to contain the same stuff you already have in the D3DXVECTOR3 representation? Taking the address of the `x' member and treating it as an array of 3 floats should work just fine. The C++ standard doesn't guarantee that it will work, of course. If that bothers you, I am sure there are some pills you can take. :)

[background=#fafbfc]You could make a conversion operator...[/background]

... but don't. There is a reason why the standard committed opted for std::string::c_str() rather than making an implicit conversion to C string.
Note that if you have a C++11 compiler, you can use explicit conversion operators which avoid many of the problems with implicit conversions.

Thanks Alvaro. I actually didn't check if D3DXVECTOR3 had an operator to return a float array for XYZ.

Got it working now, with no unnecessary float array and keeping track of XYZ pos 2 times each frame

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

This topic is closed to new replies.

Advertisement