В своем проекте я использую две разные библиотеки, и обе они предоставляют базовый прямоугольник struct. Проблема в том, что, похоже, нет способа вставить преобразование между типами, поэтому я не могу вызвать функцию в одной библиотеке с результатом функции в другой. Если бы я был автором любого из них, я мог бы создавать конверсии извне, я не могу.
библиотека а:
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, имеет ту же проблему ..)
На самом деле, ни одно из предложений не отвечает на мой вопрос, Конрад Рудольф кажется правильным. C++ на самом деле не может этого сделать. Отстой, но это правда. (Если это имеет значение, я попробую создать подкласс, как это предлагает CodingTheWheel.





В вашем случае это может быть невыполнимо, но я видел, как люди использовали небольшой препроцессор-foo, чтобы преобразовать типы в совместимость.
Даже это предполагает, что вы создаете одну или обе библиотеки.
Также возможно, что вы совсем не хотите этого делать, но хотите пересмотреть какое-то раннее решение. Или нет.
Почему бы не сделать что-то простое вроде этого: (обратите внимание, что это может / вероятно не будет компилироваться), но вы поняли ...
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;
}
Обновлено: Похоже на Коко и у меня такая же идея.
Может, можно попробовать с перегрузкой оператора? (Может быть, оператор =, который не является методом вашего класса)?
Оператор Rect = (const Rect &, const прямоугольник &)
Подробнее об этом на языке программирования C++ Бьярна Страуструпа или, может быть, на этой странице: http://www.cs.caltech.edu/courses/cs11/material/cpp/donnie/cpp-ops.html
Создайте промежуточный тип прокладки «RectangleEx» и определите пользовательские преобразования в / из сторонних строковых типов. Всякий раз, когда вы разговариваете с любым API, делайте это через класс оболочки.
Другой способ - получить class из rect или Rectangle и вставить туда преобразования / конструкторы.
Если вы не можете изменить структуры, у вас нет альтернативы написанию функции ручного преобразования, потому что операторы преобразования с перегрузкой работают только в теле класса. Другого пути нет.
Не уверен, насколько это разумно, но как насчет чего-то вроде этого:
class R
{
public:
R(const rectangle& r) { ... };
R(const Rect& r) { ... };
operator rectangle() const { return ...; }
operator Rect() const { return ...; }
private:
...
};
Затем вы можете просто обернуть каждый rectangle в R(), и все будет "правильно".
Может быть, это не так, но - в общем - наличие более одного неявного неявного преобразования может привести к двусмысленности в выражениях: предположим, что и у прямоугольника, и у Rect есть оператор &: Предположим, у вас есть R ra, rb; ra & rb; Операция & неоднозначна (может быть как прямоугольник, так и прямоугольник)
В C++ запрещено определять operator = вне класса.