Russian Qt Forum

Qt => Общие вопросы => Тема начата: SASA от Март 11, 2011, 12:00



Название: Qvariant и Automatically Cast To
Отправлено: SASA от Март 11, 2011, 12:00
Задача состоит в том, чтобы "научить" QVarint автоматически кастить конвертировать некоторые типы. Например, у меня есть тип СMyType, наследник от QString. Есть конструктор по QString. Я хочу, чтобы последняя строка кода возвращала тру.
Код:
QVarint v(QString("bla-bla"));
v.canConvert<СMyType>();


Название: Re: Qvariant и Automatically Cast To
Отправлено: Akon от Март 11, 2011, 14:40
Q_DECLARE_METATYPE(CMyType)


Название: Re: Qvariant и Automatically Cast To
Отправлено: SASA от Март 14, 2011, 10:28
Q_DECLARE_METATYPE(CMyType)
Этого не достаточно


Название: Re: Qvariant и Automatically Cast To
Отправлено: frostyland от Март 15, 2011, 09:14
Q_DECLARE_METATYPE(CMyType)
Этого не достаточно

Так не получается.
Гляньте в исходники (qvariant.cpp):
метод bool QVariant::canConvert(Type t) const может правильно кастить только тип к самому типу или же встроенные типы (см. доку)



Название: Re: Qvariant и Automatically Cast To
Отправлено: Akon от Март 15, 2011, 10:44
Код:
class MyString : public QString
{
public:
MyString() : QString() {}
explicit MyString(const char* s) : QString(s) {}
MyString(const MyString& other) : QString(other) {}
};
Q_DECLARE_METATYPE(MyString)

...

MyString myString("123");

QVariant variant;
variant.setValue(myString);

bool canConvert = variant.canConvert<MyString>();  // true

MyString myOtherString = variant.value<MyString>();
Q_ASSERT(!myOtherString.isEmpty());  // OK, not default-constructed


Извиняюсь, невнимательно прочитал первый пост.
Конечно так не будет и не должно работать - автоматический downcast к производному классу.

Код:
QVarint v(QString("bla-bla"));
v.canConvert<СMyType>();
Это же жесть - реальный экземпляр базового класса (QString("bla-bla")) кастить к производному.


Название: Re: Qvariant и Automatically Cast To
Отправлено: frostyland от Март 15, 2011, 10:53
Код:
class MyString : public QString
..................

ИМХО, у человека другая проблема - не работает даункастинг от QString к СMyType.
Пример, конечно, там корявый, такой код не вернет тру ни в каком варианте
Код
C++ (Qt)
QVarint v(QString("bla-bla"));
v.canConvert<СMyType>();
 
Но даже если хранить указатели на полиморфные типы, QVariant::canConvert не работает.
Не заточен он на такую работу



Название: Re: Qvariant и Automatically Cast To
Отправлено: SASA от Март 15, 2011, 12:28
Код:
QVarint v(QString("bla-bla"));
v.canConvert<СMyType>();
Это же жесть - реальный экземпляр базового класса (QString("bla-bla")) кастить к производному.
Здесь речь идёт не про кастить, а про конвертировать. А сконвертить можно, т.к. у СMyType есть конструктор СMyType(const QString &).

В исходниках canConvert ЖЕСТКО зашито что  к чему можно конвертить. Для решения этой проблемы я написал свои функции canConvert и convert.



Название: Re: Qvariant и Automatically Cast To
Отправлено: frostyland от Март 15, 2011, 12:59
Здесь речь идёт не про кастить, а про конвертировать. А сконвертить можно, т.к. у СMyType есть конструктор СMyType(const QString &).
В исходниках canConvert ЖЕСТКО зашито что  к чему можно конвертить. Для решения этой проблемы я написал свои функции canConvert и convert.
Кастить было написано в Вашем первом посте.
Кроме того - ИМХО, нет средств языка, позволяющих конвертировать тип к другому типу, основываясь на некоем конструкторе. Есть неявное приведение типа (или как там оно называется), если конструктор с одним параметром объявлен не explicit, например, в Вашем случае сработает вот такая конструкция

// если конструктор не explicit
Код
C++ (Qt)
CMyType(const QString &){}
// где-то в коде
Код
C++ (Qt)
CMyType mt = QString("blah");

но убей бог мою душу лаптем, если я понимаю, как это можно использовать в автоматической конвертации.
Приведите свою реализацию canConvert и convert.



Название: Re: Qvariant и Automatically Cast To
Отправлено: SASA от Март 16, 2011, 15:39
Кастить было написано в Вашем первом посте.
Блин, правда :)
Цитировать
нет средств языка, позволяющих конвертировать
Qt со своей метообъектной информацией "расширяет" возможности языка. Я пытался спросить, может в это расширении есть решение моей задачи? Например, с помощью хитрых макросов. Но ответ - нельзя.
Цитировать
Приведите свою реализацию canConvert и convert.
Она специфична для задачи. Что-то похожее на это
Код
C++ (Qt)
bool canConvert(const QVarint & _src, int _userType)
{
   if (_src.canConvert(_userType)) return true;
   if (_src.userType == QVariant::String && _userType == QMetaType::type("MyClass")) return true;
....
  return false;
}
 
Ну, вообщем, идея понятна.


Название: Re: Qvariant и Automatically Cast To
Отправлено: frostyland от Март 16, 2011, 15:42
А ну тогда понятно ))