質問

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:

...

};
役に立ちましたか?

解決

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());

他のヒント

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top