2

I am trying to create interoperability between my Math library and some of the DirectX built in methods by creating overloaded conversion operators. Basically my structs need to convert themselves to either a object or a pointer of an object it is related to in the DirectX library. Example below:

//overloaded conversion operators
Vector3D::operator D3DXVECTOR3() const;
Vector3D::operator D3DXVECTOR3*() const;

My problem lies in the fact that some of the DirectX methods have overloads that take both references and pointers so I receive an ambiguous call error when I try to pass my object. I want to make this as seamless as possible for the end user so I don't want to have to use an explicit conversion method (e.g. ToD3DXVECTOR3()) or explicitly call the operator.

So I want it to behave like this:

//signature for DirectX method
//D3DXVec3Add(D3DXVECTOR3* vect1, D3DXVECTOR3* vect2) or
//D3DXVec3Add(D3DXVECTOR& vect1, D3DXVECTOR3& vect2)

Vector3D v1(1,1,1);
Vector3D v2(2,2,2);

D3DXVec3Add(v1, v2);

Instead of like this:

D3DXVec3Add(v1.toD3DXVECTOR3(), v2.toD3DXVECTOR3());

I am not sure this is even possible but are there any suggestions as to how I can fix the ambiguity?

Edit:

Although I cant just rely on the implicit conversions I am going to go with the suggestion left by Mr.C64. One difference though is that the Vector3D struct does not contain the objects it can convert to as member variables:

struct Vector3D
{
float X;
float Y;
float Z;

...

//Implicit conversion operators
operator D3DXVECTOR3() const;
operator D3DXVECTOR3*() const;
operator DirectX::XMFLOAT3() const;
operator DirectX::XMFLOAT3*() const;
operator DirectX::XMVECTOR() const;
operator DirectX::XMVECTOR*() const;

...

//Explicit conversion methods
D3DXVECTOR3         ToD3DXVECTOR3() const;
static Vector3D     FromD3DXVECTOR3(const D3DXVECTOR3& vector);
DirectX::XMFLOAT3   ToXMFLOAT3() const;
static Vector3D     FromXMFLOAT3(const DirectX::XMFLOAT3& value);
DirectX::XMVECTOR   ToXMVECTOR() const;
static Vector3D     FromXMVECTOR(const DirectX::XMVECTOR& value);

private:

...

};
dehersh
  • 43
  • 7
  • I was running into a problem with passing references of my stuct to a method that took a pointer to one of the DirectX objects (e.g. the methods took a D3DXVECTOR3*). The reference returned a pointer to my struct and it was unable to convert it. Overloading the address of operator wasn't working either because the stuct has more than one type it can convert to. – dehersh Jan 30 '13 at 17:06

2 Answers2

2

Would it be possible for you to derive your Vector3D class from D3DXVECTOR3? Just like ATL::CRect class derives from Win32 RECT structure (adding convenient methods).

If this is not possible or just doesn't fit well in your particular design context, consider offering explicit methods for conversions, just like std::string offers a .c_str() method to get a const char* pointer, instead of using an implicit conversion. You may find this blog post interesting as well:

Reader Q&A: Why don’t modern smart pointers implicitly convert to *?

Moreover, I noted that D3DXVec3Add() just uses pointers to instances of D3DXVECTOR3. So, in case you can't derive your own class from D3DXVECTOR3 (as you stated in a comment), it would make sense to provide a couple of getters (both const and non-const versions), like this:

class Vector3D
{
public:

  ....

  // Get read-only access to wrapped D3DX vector
  const D3DXVECTOR3* Get() const
  {
      return &m_vec;
  }

  // Get read-write access to wrapped D3DX vector
  D3DXVECTOR3* Get()
  {
      return &m_vec;
  }

private:
  D3DXVECTOR3 m_vec;
};

and then use them like this:

Vector3D v1;
Vector3D v2;
Vector3D vSum;
D3DXVec3Add(vSum.Get(), v1.Get(), v2.Get());
Mr.C64
  • 41,637
  • 14
  • 86
  • 162
  • Thanks for the input, at this point I am unable to derive from the DirectX class so I will probably have to just go with the explicit conversion method route. If only you could set a priority to overloaded methods (e.g. if both exist call this one) :) – dehersh Jan 30 '13 at 17:23
  • @dehersh: Since it seems that `D3DXVec3Add()` uses _pointers_ (instead of references), I'd just provide a couple of getters, both `const` and non-`const`. I've edited my answer considering this information. – Mr.C64 Jan 30 '13 at 17:39
  • Thanks again for the help. The Vector3D struct can convert to more than just a D3DXVECTOR3 though. It can also convert to an XMVECTOR or XMFLOAT3 so I will have to make the getters more specific (GetD3DXVECTOR3, GetXMFLOAT3, etc). If the implicit conversion is ambiguous I will use the getters and if not I will use the conversion operator. – dehersh Jan 30 '13 at 17:52
  • I am going to post a sample of my struct. – dehersh Jan 30 '13 at 17:53
1

If you can compile using the C++11 standard, you could make the conversions explicit. See https://stackoverflow.com/a/8239402/713961

Community
  • 1
  • 1
Matt Kline
  • 10,149
  • 7
  • 50
  • 87