Russian Qt Forum

Qt => Общие вопросы => Тема начата: EhTemka от Декабрь 04, 2008, 12:34



Название: QVariant NULL == 0?
Отправлено: EhTemka от Декабрь 04, 2008, 12:34

Всем привет.

Qt 4.2.3

Вот такой код :

Код
C++ (Qt)
       QVariant varNull(QVariant::Double);
QVariant var0 = 0.0;
if (varNull == var0) {
EH_COUT2("varNull.isNull()", varNull.isNull())EH_ENDL; // мои макросы для вывода в стандартный поток
EH_COUT2("var0.isNull()", var0.isNull())EH_ENDL;
}
 

вывод :
varNull.isNull()  1
var0.isNull()     0

То есть внутрь if заходит.

Столкнулся я с этим при работе с базой. Есть в одной таблице поле типа double,
где могут быть любые значения, в том числе 0. А могут быть и не заданы, что имеет свой смысл.
Запрос всё возвращает правильно, т.е. если 0, то 0 и query.value(i) не isNull; если не задано, то query.value(i) - isNull.
И в некоторых местах программы мне надо сравнивать эти значения. И вот собственно натыкаюсь на то, что 0 и нету оказывается одно и тоже, что в контексте моей программы недопустимо. То есть конечно дополнительные проверки всё разрешают, но...

Вопрос к гуру. Является ли это багом, или я что-то не понимаю?




Название: Re: QVariant NULL == 0?
Отправлено: Rcus от Декабрь 04, 2008, 12:40
Код
C++ (Qt)
bool QVariant::cmp(const QVariant &v) const
{
   QVariant v2 = v;
   if (d.type != v2.d.type) {
       if (qIsNumericType(d.type) && qIsNumericType(v.d.type)) {
           if (qIsFloatingPoint(d.type) || qIsFloatingPoint(v.d.type))
               return qFuzzyCompare(toDouble(), v.toDouble());
           else
               return toLongLong() == v.toLongLong();
       }
       if (!v2.canConvert(Type(d.type)) || !v2.convert(Type(d.type)))
           return false;
   }
   return handler->compare(&d, &v2.d);
}
 
Помоему все нормально.


Название: Re: QVariant NULL == 0?
Отправлено: EhTemka от Декабрь 04, 2008, 13:09
Цитировать
Помоему все нормально.

Что вы имеете ввиду?

в функции что ты привел в моем случае срабатывает
Код:
return handler->compare(&d, &v2.d);

и возвращает true.

Это нормально?

P.S. А как вы создаете такой красивый код в сообщении?


Название: Re: QVariant NULL == 0?
Отправлено: kirill от Декабрь 04, 2008, 13:29
GeShi - комбобокс при ответе - используй его.
Код
C++ (Qt)
 


Название: Re: QVariant NULL == 0?
Отправлено: Rcus от Декабрь 04, 2008, 15:45
собственно говоря если вам нужно пустое значение double, то почему бы не воспользоваться
Код
C++ (Qt)
std::numeric_limits<double>::quiet_NaN();


Название: Re: QVariant NULL == 0?
Отправлено: EhTemka от Декабрь 05, 2008, 11:06
Вопрос не в том, что делать, А в том что является ли это багом или нет (всмысле репортить ли троллям).

Ведь к примеру делегат понимает, где нул а где ноль, то есть для него разница есть, а при сравнении получается что нет..


Название: Re: QVariant NULL == 0?
Отправлено: Rcus от Декабрь 05, 2008, 11:48
Код
C++ (Qt)
QVariant(0.0)==QVariant(QVariant::Double)
QVariant(0.0).toDouble()==QVariant(QVariant::Double).toDouble()

Я бы очень удивился если бы эти выражения давали разный результат :)


Название: Re: QVariant NULL == 0?
Отправлено: ритт от Декабрь 05, 2008, 12:01
это не баг.
в первом случае ты инициализируешь вариант пустым значением - в итоге получаешь типизированный вариант с неопределённым значением, а isNull() возвращает правду;
во втором случае ты инициализируешь вариант конкретным значением - в итоге isNull() возвращает ложь, т.к. вариант типизирован и определён.


Название: Re: QVariant NULL == 0?
Отправлено: BRE от Декабрь 05, 2008, 12:15
Я так понял, что EhTemka интересует почему QVariant::null равен QVariant::0.
Сейчас тоже сам задумался... ???


Название: Re: QVariant NULL == 0?
Отправлено: Tonal от Декабрь 05, 2008, 12:43
А что возвернёт конструкция QVariant("0") == QVariant(0)?
Или QVariant(0.0) == QVariant(0)?

Если true, то с null-ом поведение вполне логично. :)


Название: Re: QVariant NULL == 0?
Отправлено: EhTemka от Декабрь 05, 2008, 13:03
И все - таки мне кажется

Цитировать
типизированный вариант с неопределённым значением
НЕ должен равняться  типизированному варианту с заданным значением. А 0.0 - это заданное значение...


Название: Re: QVariant NULL == 0?
Отправлено: ритт от Декабрь 06, 2008, 04:58
при доступе к значению неопределённый вариант кастит значение к дефолтовуму пустому, но при этом остаётся пустым (isNull() == true)
сравниваешь 0.0 и 0.0 - чего ожидаешь?


Название: Re: QVariant NULL == 0?
Отправлено: EhTemka от Декабрь 06, 2008, 15:20
Я ожидал более разумного поведения оператора сравнения у QVariant. Сейчас мне приходится делать дополнительные проверки на null перед тем как производить сравнение, т.е. этот код мог бы вполне быть внутри оператора. Я в первом посте привел пример, когда null(незадано) и ноль разные по смыслу и считаю это (null != 0) вполне логичным. Если isNull == true, то должно быть все равно, какое значение у второго сравниваемого элемента, возвращать false (если он конечно не isNull тоже). Ведь я сравниваю не даблы а варианты. И QVariant, имхо, должен это понимать и кастить значение при сравнении в последнюю очередь, когда все остальные условия проверены.


Название: Re: QVariant NULL == 0?
Отправлено: Rcus от Декабрь 06, 2008, 15:34
Ну если вам так хочется чтобы в вашем коде было различие между null и 0 вариантами то сделайте себе инлайн функцию сравнения с дополнительной проверкой.
В Qt такое тащить помоему смысла нет (попробуйте проверить, будет ли сама библиотека работать если в оператор сравнения вставить проверку isNull), да и слишком много стороннего кода зависит от данного поведения.