Pergunta

Estou usando duas bibliotecas diferentes em meu projeto e ambas fornecem um retângulo básico struct.O problema disso é que parece não haver como inserir uma conversão entre os tipos, então não consigo chamar uma função em uma biblioteca com o resultado de uma função na outra.Se eu fosse o autor de qualquer um deles, poderia criar conversões, de fora, não posso.

biblioteca A:

typedef struct rectangle { sint16 x; sint16 y; uint16 w; uint16 h; } rectangle;

biblioteca b:

class Rect {
  int x; int y; int width; int height;
  /* ... */
};

Agora não consigo fazer um conversor class, porque o C++ procurará uma conversão apenas em uma etapa.Isto é provavelmente uma coisa boa, porque haveria muitas possibilidades envolvendo a criação de novos objetos de todos os tipos.

Não consigo fazer um operador que pegue o struct de a e fornece um objeto do class de b:

foo.cpp:123 error: ‘operator b::Rect(const rectangle&)’ must be a nonstatic member function

Então, existe uma maneira sensata de contornar isso?

editar:

Talvez eu também deva salientar que eu realmente gostaria de alguma solução que tornasse o trabalho com o resultado perfeito, já que não espero ser esse codificador.(Embora eu concorde, a conversão tradicional e explícita teria sido uma boa escolha.O outro ramo, reinterpret_cast tem o mesmo problema..)

editar2:

Na verdade, nenhuma das sugestões realmente responde à minha pergunta, Konrad Rodolfo parece estar correto.Na verdade, C++ não pode fazer isso.É uma merda, mas é verdade.(Se fizer alguma diferença, tentarei subclassificar conforme sugerido por Codificando a Roda.

Foi útil?

Solução

Se você não puder modificar as estruturas, não terá alternativa a não ser escrever uma função de conversão manual, porque a sobrecarga dos operadores de conversão só funciona dentro do corpo da classe.Não há outra maneira.

Outras dicas

Crie um tipo de calço intermediário "RectangleEx"e defina conversões personalizadas de/para tipos de string de terceiros.Sempre que você falar com qualquer uma das APIs, faça-o por meio da classe shim.

Outra maneira seria derivar um class de qualquer um rect ou Rectangle, e insira conversões/construtores lá.

Não tenho certeza de quão sensato isso é, mas que tal algo assim:

class R
{
public:
    R(const rectangle& r) { ... };
    R(const Rect& r) { ... };

    operator rectangle() const { return ...; }
    operator Rect() const { return ...; }

private:
    ...
};

Então você pode simplesmente embrulhar cada rectangle em R() e a "coisa certa" acontecerá.

Pode não ser viável no seu caso, mas já vi pessoas empregarem um pouco de pré-processador para massagear a compatibilidade dos tipos.

Mesmo isso pressupõe que você esteja construindo uma ou ambas as bibliotecas.

Também é possível que você não queira fazer isso, mas queira reavaliar alguma decisão antecipada.Ou não.

Por que não algo simples como isto:(observe que isso pode/provavelmente não será compilado), mas você entendeu ...


private Rect* convert(const rectangle& src)
{
    return new Rect(src.x,src.y,src.w,src.h);
}
int main()
{
    rectangle r;
    r.x = 1;
    r.y = 2;
    r.w = 3;
    r.h = 4;

    Rect* foo = convert(&r);
    ...
    delete foo;

}

EDITAR: Parece que Koko e eu temos a mesma ideia.

Se o structeram os mesmos internamente, você poderia fazer um reinterpret_cast;no entanto, como parece que você tem campos de 16 bits versus 32 bits, provavelmente ficará preso na conversão em cada chamada ou na gravação de wrappers para todas as funções de uma das bibliotecas.

Talvez você possa tentar com sobrecarga de operador?(Talvez um operador = que não seja um método da sua classe)?

Operador Rect= (const Rect&,const retângulo&)

Mais sobre isso na linguagem de programação C++ de Bjarne Stroustrup ou talvez nesta página: http://www.cs.caltech.edu/courses/cs11/material/cpp/donnie/cpp-ops.html

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top