Как я могу конвертировать типы в C ++? - PullRequest
0 голосов
/ 26 августа 2008

Я использую две разные библиотеки в своем проекте, и обе они предоставляют базовый прямоугольник struct. Проблема в том, что, похоже, нет способа вставить преобразование между типами, поэтому я не могу вызвать функцию в одной библиотеке с результатом из функции в другой. Если бы я был автором любого из них, я мог бы создавать конверсии извне, я не могу.

библиотека a:

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

библиотека b:

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

Теперь я не могу сделать конвертер class, потому что C ++ будет искать преобразование только за один шаг. Вероятно, это хорошо, потому что было бы много возможностей, связанных с созданием новых объектов всех типов.

Я не могу сделать оператор, который берет struct из a и поставляет объект class из b:

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

Итак, есть ли разумный способ обойти это?

редактирование:

Возможно, мне следует также отметить, что мне бы очень хотелось какое-то решение, позволяющее работать с результатом без проблем, поскольку я не ожидаю, что стану этим кодером. (Хотя я согласен, старая школа, явное, преобразование было бы хорошим выбором. Другая ветвь, reinterpret_cast имеет ту же проблему ..)

edit2:

На самом деле, ни одно из предложений на самом деле не отвечает на мой настоящий вопрос, Конрад Рудольф кажется правильным. C ++ на самом деле не может этого сделать. Отстой, но это правда. (Если это имеет какое-то значение, я собираюсь попробовать создать подклассы, как это предложено CodingTheWheel .

Ответы [ 7 ]

4 голосов
/ 26 августа 2008

Создайте промежуточный тип прокладки "RectangleEx" и определите пользовательские преобразования в / из сторонних строковых типов. Всякий раз, когда вы говорите с любым API, делайте это через класс shim.

Другим способом было бы получить class из rect или Rectangle и вставить туда преобразования / конструкторы.

3 голосов
/ 26 августа 2008

Не уверен, насколько это разумно, но как насчет этого:

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

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

private:
    ...
};

Тогда вы можете просто обернуть каждую rectangle в R(), и произойдет "правильная вещь".

2 голосов
/ 26 августа 2008

Если вы не можете изменить структуры, у вас нет альтернативы написанию функции ручного преобразования, поскольку перегрузка операторов преобразования работает только внутри тела класса. Другого пути нет.

0 голосов
/ 26 августа 2008

Может быть, вы могли бы попробовать это с перегрузкой оператора? (Может быть, оператор =, который не является методом вашего класса)?

Оператор Rect = (const Rect &, const rectangle &)

Подробнее об этом на языке программирования C ++ Бьярна Страуструпа или, возможно, на этой странице: http://www.cs.caltech.edu/courses/cs11/material/cpp/donnie/cpp-ops.html

0 голосов
/ 26 августа 2008

Почему бы не сделать что-то простое: (обратите внимание, что это может / вероятно не скомпилируется), но вы поняли ...


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;

}

РЕДАКТИРОВАТЬ: Похоже, Коко, и у меня та же идея.

0 голосов
/ 26 августа 2008

Если бы struct были одинаковыми внутри, вы могли бы сделать reinterpret_cast; однако, поскольку похоже, что у вас 16-битные или 32-битные поля, вы, вероятно, застряли при конвертации при каждом вызове или при написании оболочек для всех функций одной из библиотек.

0 голосов
/ 26 августа 2008

Это может быть неосуществимо в вашем случае, но я видел людей, использующих небольшой препроцессор-foo для преобразования типов в совместимость.

Даже при этом предполагается, что вы создаете одну или обе библиотеки.

Также возможно, что вы вообще не хотите этого делать, но хотите переоценить какое-то раннее решение. Или нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...