Перегрузка оператора преобразования — неоднозначность функции

Я пытаюсь создать совместимость между моей библиотекой 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:

...

};

2

Решение

Было бы возможно для вас выводить ваш 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());
2

Другие решения

Если вы можете скомпилировать с использованием стандарта C ++ 11, вы можете сделать преобразования explicit, Увидеть https://stackoverflow.com/a/8239402/713961

1