Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Шаблоны функций 
V
    Опции темы
SABROG
Дата 21.4.2008, 21:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



У меня много однотипных параметров, но в принципе эти типы: QString, double, int, unsigned int, bool, unsigned char. Поэтому, чтобы не писать для каждого типа свою реализацию функции я решил воспользоваться шаблонами:

Код

template <class T>
bool Dict::cTemplates::setParam(Tp::tParTypes parType, T)
{
     QString parName;
    switch(parType)
    {
    case Tp::Name:
        parName = "name";      
        break;
        
    };
    parent->pBase->prepare(QString("UPDATE tt SET %1=:par WHERE inc=:inc;").arg(parName));
    parent->pBase->bindValue(QLatin1String(":par"), qVariantFromValue(T));
    parent->pBase->bindValue(QLatin1String(":inc"), inc);
    if (!parent->pBase->exec())
    {
        qDebug(qPrintable(parent->pBase->lastError().text()));
        return false;
    }
    else
    {
        changeDate = QDateTime::currentDateTime();
        return true;
    }
}


Соответственно получаю косяк:

Цитата

src\Dict.cpp:976: error: expected primary-expression before ')' token

(13 строка на форуме в секции кода, где юзается T)

Как бы так исхитрится, чтобы заставить QVariant хавать то что он и будет хавать в принципе, но видимо его пугает, что вместо стандартных типов могут быть кастомы ?
---
Всё, допетрил. Ключевой момент:

Код

QVariant parVal(T);


Это сообщение отредактировал(а) SABROG - 21.4.2008, 21:38


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
SABROG
Дата 22.4.2008, 11:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



Нет, и все-таки есть проблема. Не удается преобразовать ни в какой тип данных:

Код

QString name;
name = T;


Получаю: error: expected primary-expression before ';' token

Я уж этот QVariant и через convert(QVariant::String) и через .value<QString>() пытался, ну никак не хочет. Теряется смысл шаблона, я думал компилятор должен закрывать глаза на это и подставлять только в том случае, когда идет непосредственный вызов функции из кода с нужными типами в параметрах.

Это сообщение отредактировал(а) SABROG - 22.4.2008, 11:47


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
pilotnet
Дата 22.4.2008, 12:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 43
Регистрация: 22.4.2008

Репутация: нет
Всего: нет



Что-то я не допераю 
вы везде пишите 
bool Dict::cTemplates::setParam(Tp::tParTypes parType, T)
parent->pBase->bindValue(QLatin1String(":par"), qVariantFromValue(T));

"Т" - это ведь тип данных а не переменная этого типа 

это должно выглядеть как 
bool Dict::cTemplates::setParam(Tp::tParTypes parType,const T &value)

а потом 
parent->pBase->bindValue(QLatin1String(":par"), qVariantFromValue(value));

или я не о том ?
PM MAIL   Вверх
SABROG
Дата 22.4.2008, 12:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



О том, все правильно. Мой косяк, допетрил уже. Сейчас не могу другое понять, почему компилятор считает, что тип изначально передается как QString ?

Код

template <class T>
bool Dict::cTemplates::setParam(Tp::tParTypes parType, const T &parVal)
...
QString name = parVal; // все ок!
stour *pTour = (stour *)parVal; // косяк! error: cannot convert `parVal' from type `const QString' to type `Dict::stour*'


---
Добавил еще пару функций с разными типами параметров, теперь характер ошибок изменился. Заподло, вот действительно было бы проще воспользоваться Copy->Paste и не заморачиваться насчет дублирующего кода.

Это сообщение отредактировал(а) SABROG - 22.4.2008, 12:29


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
pilotnet
Дата 22.4.2008, 12:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 43
Регистрация: 22.4.2008

Репутация: нет
Всего: нет



потому что в темплейтах определение типа происходит на стадии компиляции
компилятор генерит код для каждого типа  "T"


PM MAIL   Вверх
SABROG
Дата 22.4.2008, 12:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



Цитата(pilotnet @ 22.4.2008,  12:28)
потому что в темплейтах определение типа происходит на стадии компиляции
компилятор генерит код для каждого типа  "T"

Значит придется возвращаться к тому с чего я начал. Обидно 2 вечера и утро потратил на разбор характера ошибок. Воспользуюсь тогда void * и cast'ами.

Это сообщение отредактировал(а) SABROG - 22.4.2008, 12:32


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
pilotnet
Дата 22.4.2008, 12:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 43
Регистрация: 22.4.2008

Репутация: нет
Всего: нет



чем не нравиться

Код

bool Dict::cTemplates::setParam(Tp::tParTypes parType, const T &parVal)

QVariant value(parVal);

 parent->pBase->bindValue(QLatin1String(":par"), value );


PM MAIL   Вверх
SABROG
Дата 22.4.2008, 12:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



класс сTemplates имеет все те же члены, что в базе данных, поэтому их надо синхронно изменять:

Например меняя имя (name), надо изменить и запись в БД
Код

name = parVal; // QString name;
...
parent->pBase->bindValue(QLatin1String(":par"), value );


name это QString. Помимо имени есть еще параметры других типов, например ссылка на объект, которая может менятся, но в базе данных она принимает вид ключа с типом unsigned int.

Код

tour = parVal; // stour *tour;
value.setValue(tour->inc);
...
parent->pBase->bindValue(QLatin1String(":par"), value);

---
Изначально идея была такая и видимо к ней придется вернутся:

Код

bool Dict::cTemplates::setName(const QString &newtitle)
{
   parent->pBase->prepare(QLatin1String("UPDATE tt SET name=:name WHERE inc=:inc;"));
   parent->pBase->bindValue(QLatin1String(":name"), newtitle);
   parent->pBase->bindValue(QLatin1String(":inc"), inc);
   if (!parent->pBase->exec())
   {
       qDebug(qPrintable(parent->pBase->lastError().text()));
       return false;
   }
   else
   {
       name = newtitle;
       changeDate = QDateTime::currentDateTime();
       return true;
   }
}
bool Dict::cTemplates::setNote(const QString &newnote)
{
    parent->pBase->prepare(QLatin1String("UPDATE tt SET note=:note WHERE inc=:inc;"));
    parent->pBase->bindValue(QLatin1String(":note"), newnote);
    parent->pBase->bindValue(QLatin1String(":inc"), inc);
    if (!parent->pBase->exec())
    {
        qDebug(qPrintable(parent->pBase->lastError().text()));
        return false;
    }
    else
    {
        note = newnote;
        changeDate = QDateTime::currentDateTime();
        return true;
    }    
}
bool Dict::cTemplates::setCom(double newcom)
{
    parent->pBase->prepare(QLatin1String("UPDATE tt SET comission=:comission WHERE inc=:inc;"));
    parent->pBase->bindValue(QLatin1String(":comission"), newcom);
    parent->pBase->bindValue(QLatin1String(":inc"), inc);
    if (!parent->pBase->exec())
    {
        qDebug(qPrintable(parent->pBase->lastError().text()));
        return false;
    }
    else
    {
        Com = newcom;
        changeDate = QDateTime::currentDateTime();
        return true;
    }  
}



Я бы не мог ЭТО назвать хорошим стилем программирования...

Это сообщение отредактировал(а) SABROG - 22.4.2008, 12:57


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
pilotnet
Дата 22.4.2008, 13:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 43
Регистрация: 22.4.2008

Репутация: нет
Всего: нет



дак тогда и передавай в эту функцию 
уже (unsigned int)tour->inc

все равно тебе что передовать надо разбираться самому
в зависимости от типа
PM MAIL   Вверх
SABROG
Дата 22.4.2008, 13:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



Выбросил шаблон и сделал так:

Код

bool Dict::cTemplates::setName(const QString &newtitle)
{
    if (setParam(Tp::Name, newtitle))
    {
        name = newtitle;
    }
}

bool Dict::cTemplates::setParam(Tp::tParTypes parType, const QVariant &parVal)
{
    QString parName;
    switch(parType)
    {
    case Tp::Name:
        parName = "name";
        break;
    case Tp::Note:
        parName = "note";
        break;
    case Tp::Tour:
        parName = "tour";
        break;
    case Tp::Country:
        parName = "country";
        break;
    case Tp::Operator:
        parName = "operator";
        break;
    case Tp::Postfix:
        parName = "postfix";
        break;
    case Tp::Owner:
        parName = "owner";
        break;
    case Tp::OpComission:
        parName = "opcomission";
        break;
    case Tp::Comission:
        parName = "comission";
        break;
    case Tp::Currency:
        parName = "currency";
        break;
    case Tp::SposNote:
        parName = "sposnote";
        break;
    case Tp::SpogNote:
        parName = "spognote";
        break;
    case Tp::CatNote:
        parName = "catnote";
        break;
    case Tp::SpoSort:
        parName = "sposort";
        break;
    case Tp::XmlEngine:
        parName = "xmlengine";
        break;
    case Tp::Type:
        parName = "type";
        break;
    case Tp::tSort:
        parName = "sort";
        break;
    };
    parent->pBase->prepare(QString("UPDATE tt SET %1=:par WHERE inc=:inc;").arg(parName));
    parent->pBase->bindValue(QLatin1String(":par"), parVal);
    parent->pBase->bindValue(QLatin1String(":inc"), inc);
    if (!parent->pBase->exec())
    {
        qDebug(qPrintable(parent->pBase->lastError().text()));
        return false;
    }
    else
    {
        changeDate = QDateTime::currentDateTime();
        return true;
    }
}



--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
Lazin
Дата 22.4.2008, 14:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 2
Всего: 154



не знаю что такое QVariant, но мне кажется что boost::variant is more suitable 

Код

bool Dict::cTemplates::setParam(boost::variant & v)
{
  struct helper_t : : public boost::static_visitor<>
  {
     void operator (QString & str) {..здесь.сохраняешь.в.бд..}
     void operator (double f) {..и.здесь..}
      ......
  } helper;
  boost::apply_visitor(helper, v);
}

PM MAIL Skype GTalk   Вверх
SABROG
Дата 22.4.2008, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



С бустом у меня что-то никак не склеивается, не хочет под mingw собирать. Я так понимаю это паттерн ?
Так сразу и не скажешь как он работает.


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
Lazin
Дата 22.4.2008, 15:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 2
Всего: 154



boost::apply_visitor вызывает одну из перегруженных версий оператора () функтора helper, в зависимости от типа своего содержимого
если там строка, то вызовется
void operator (QString & str) 
если int, то 
void operator (int)

PM MAIL Skype GTalk   Вверх
SABROG
Дата 22.4.2008, 16:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Hacker
****


Профиль
Группа: Завсегдатай
Сообщений: 2481
Регистрация: 18.9.2006

Репутация: 81
Всего: 91



А чем же это отличается от обычной перегрузки параметров ?

К тому же у меня параметры хоть и имеют разные типы, но эти типы могут быть общими для двух разных параметров.


--------------------
Национальная группа Russian Federation на QtCentre.
PM MAIL   Вверх
Lazin
Дата 22.4.2008, 16:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 2
Всего: 154



Цитата(SABROG @  22.4.2008,  16:18 Найти цитируемый пост)
А чем же это отличается от обычной перегрузки параметров ?

тем что тебе не нужно проверять вручную, что у тебя в variant переменной, будет вызвана правильная ф-я

Цитата(SABROG @  22.4.2008,  16:18 Найти цитируемый пост)
К тому же у меня параметры хоть и имеют разные типы, но эти типы могут быть общими для двух разных параметров. 

я это должен был по положению звезд определить  smile 
PM MAIL Skype GTalk   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.1072 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.