Я пытаюсь создать совместимость между моей библиотекой Math и некоторыми встроенными в DirectX методами, создавая перегруженные операторы преобразования. В основном мои структуры должны преобразовывать себя либо в объект, либо в указатель на объект, с которым он связан в библиотеке DirectX. Пример ниже:
//overloaded conversion operators
Vector3D::operator D3DXVECTOR3() const;
Vector3D::operator D3DXVECTOR3*() const;
Моя проблема заключается в том, что некоторые методы DirectX имеют перегрузки, которые принимают и ссылки, и указатели, поэтому я получаю неоднозначную ошибку вызова, когда пытаюсь передать свой объект. Я хочу сделать это как можно более незаметным для конечного пользователя, поэтому я не хочу использовать явный метод преобразования (например, ToD3DXVECTOR3 ()) или явно вызывать оператор.
Поэтому я хочу, чтобы он вел себя так:
//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);
Вместо этого:
D3DXVec3Add(v1.toD3DXVECTOR3(), v2.toD3DXVECTOR3());
Я не уверен, что это даже возможно, но есть ли какие-либо предложения относительно того, как я могу исправить неоднозначность?
Редактировать:
Хотя я не могу просто полагаться на неявные преобразования, я собираюсь пойти на предложение, оставленное Mr.C64. Одно из отличий состоит в том, что структура Vector3D не содержит объектов, в которые она может преобразовываться как переменные-члены:
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:
...
};
Было бы возможно для вас выводить ваш Vector3D
класс от D3DXVECTOR3
? Как ATL::CRect
класс происходит от Win32 RECT
структура (добавление удобных методов).
Если это невозможно или просто не вписывается в ваш конкретный контекст проектирования, подумайте о том, чтобы предложить явные методы для конверсий, как std::string
предлагает .c_str()
способ получить const char*
указатель, вместо использования неявного преобразования. Вы можете также найти этот пост в блоге интересным:
Читатель Q&A: Почему современные умные указатели неявно не конвертируются в *?
Более того, я отметил, что D3DXVec3Add()
просто использует указатели в случаях D3DXVECTOR3
, Так что, если вы не можете получить свой собственный класс из D3DXVECTOR3
(как вы указали в комментарии), имеет смысл предоставить пару получателей (оба const
и неconst
версии), вот так:
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;
};
а затем использовать их так:
Vector3D v1;
Vector3D v2;
Vector3D vSum;
D3DXVec3Add(vSum.Get(), v1.Get(), v2.Get());
Если вы можете скомпилировать с использованием стандарта C ++ 11, вы можете сделать преобразования explicit
, Увидеть https://stackoverflow.com/a/8239402/713961