std::array<float, 3> foo();
void bar(float *);
int main(int, char **) {
bar(foo().data());
}
return a float array in a function
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!!
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. :)
... 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.[background=#fafbfc]You could make a conversion operator...[/background]
Note that if you have a C++11 compiler, you can use explicit conversion operators which avoid many of the problems with implicit conversions.