2009-06-09 3 views
0

У меня есть этот следующий код:C++ наследование Qt проблема QString

template <class T> 
bool loadCSV (const QString &filename, map<T,int> &mapping){ 
    QFile boxfile; 
    boxfile.setFileName(filename); 
    QString line; 
    QStringList list; 

    if (!boxfile.open(QIODevice::ReadOnly)){ 
     cout << "Could not open box data file." << endl; 
     return false; 
    } 

    QTextStream stream2(&boxfile); 

    while (!stream2.atEnd()){ 
     line = stream2.readLine(); 
     list = line.split(','); 
     mapping[list.front().toInt()]=list.back().toInt();  
    } 

    return true; 
} 

Он принимает файл CSV и вставляет его в:

map<int, int> mapping 

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

map<string, int> mapping 

Структура. Теперь для этого необходимо изменить конечную строку в цикле while, и я не уверен, что это лучший способ достичь этого.

я мог придумать несколько способов:

  1. некоторые, как определить тип и иметь какой-то условной линии в там (я на самом деле не уверен, если это возможно, и если это так, как это сделать . это

  2. добавить функцию класса в QStringList сделать это

Я попробовал вариант 2 и сделал это:.

void QStringList::cInsert(map<int,int> &mapping){ 
    mapping[this->front().toInt()]=this->back().toInt(); 
} 

void QStringList::cInsert(map<string,int> &mapping){ 
    mapping[(this->front()).toAscii()]=this->back().toInt(); 
} 

Это не сработало, поскольку мне также необходимо было определить эти функции в классе QStringList, и поэтому это будет немного беспорядочно. Вместо. Я стараюсь, чтобы наследовать от QStringList:

class myQStringList: public QStringList{ 
    public: 
     void cInsert(map<int,int> &mapping); 
     void cInsert(map<string,int> &mapping); 
}; 

void myQStringList::cInsert(map<int,int> &mapping){ 
    mapping[this->front().toInt()]=this->back().toInt(); 
} 

void myQStringList::cInsert(map<string,int> &mapping){ 
    mapping[(this->front()).toAscii()]=this->back().toInt(); 
} 

А затем изменить код:

template <class T> 
bool loadCSV (const QString &filename, map<T,int> &mapping){ 
    QFile boxfile; 
    boxfile.setFileName(filename); 
    QString line; 
    myQStringList list; 

if (!boxfile.open(QIODevice::ReadOnly)){ 
    cout << "Could not open box data file." << endl; 
    return false; 
} 

QTextStream stream2(&boxfile); 

while (!stream2.atEnd()){ 
    line = stream2.readLine(); 
    list = line.split(','); 
     list.cInsert(mapping); 
} 

return true;} 

НО. Я получаю сообщение об ошибке в связи с назначением line.split/список:

main.cpp:123: error: no match for 'operator=' in 'list = QString::split(const QChar&, QString::SplitBehavior, Qt::CaseSensitivity) const(((const QChar&)(&QChar(44))), KeepEmptyParts, CaseSensitive)' 

Я не уверен, что эта ошибка и не уверен, что если это делать с оператором правопреемником/копия не наследуется?

И по отношению к фактическому новому классу, я получаю эту ошибку:

main.cpp:104: error: no match for 'operator[]' in 'mapping[QString::toAscii() const()]' 
c:/qt/mingw/bin/../lib/gcc/mingw32/3.4.2/../../../../include/c++/3.4.2/bits/stl_map.h:332: note: candidates are: _Tp& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = std::string, _Tp = int, _Compare = std::less<std::string>, _Alloc = std::allocator<std::pair<const std::string, int> >] 
main.cpp: In function `bool loadCSV(const QString&, std::map<T, int, std::less<_Key>, std::allocator<std::pair<const T,int> > >&) [with T = int]': 

который я просто не понимаю. Может кто-нибудь объяснить?

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

ответ

0

Я решил эту проблему, явно литье:

list = (const myQStringList&) line.split(','); 
void myQStringList::cInsert(map<string,int> &mapping){ 
    mapping[(string)(this->front()).toAscii()]=this->back().toInt(); 
} 
+0

У вас также есть метод QString :: toStdString(). И QString :: fromStdString() также ... –

+0

Не забудьте принять свой собственный ответ! :) – ralphtheninja

+0

Кастинг в стиле C на C++ - это зло. Вместо этого вы можете использовать static_cast .. или dynamic, reinterpret и const_cast в зависимости от ваших целей. Наряду с qobject_cast и qvariant_cast в программе Qt C++. –

2

Я хотел бы переместить преобразование из QString к типу T за пределами функции.Таким образом, есть что-то вроде:

template< typename T> 
struct converter { }; 

template<> 
struct converter< int> 
{ 
static int convert(const QString& source) 
{ 
    return source.toInt(); 
} 
}; 

template<> 
struct converter< std::string> 
{ 
static std::string convert(const QString& source) 
{ 
    return source.toStdString(); 
} 
}; 

template< typename T> 
T convertFromString(const QString& source) 
{ 
    return converter<T>::convert(source); 
} 

Затем использовать эту функцию преобразования в цикле (в то время):

Вместо

mapping[list.front().toInt()]=list.back().toInt(); 

пишут:

mapping[ convert<T>(list.front())]=list.back().toInt(); 

Примечание: Преобразователь класса (a и две его специализации), поэтому функция преобразования может использоваться как функция шаблона (аналогично static_cast или boost: lexical_cast, если хотите).

Я не пытался скомпилировать код. Это просто идея.

1

Когда дело доходит до CSV-файлов, Qt обеспечивает четкую функциональность с помощью функции QString :: section. Итак, для выяснения необходимых столбцов я обрабатываю заголовок следующим образом:

int AmountInd = (line.left(line.indexOf("Amount")).count(','); 

, чтобы получить индекс этой колонки. Тогда для будущих линий извлечь подстроку этой колонки:

QString AmountStr = (line.section(',', AmountInd, AmountInd); 
double Amount = AmountStr.toDouble(); 

Надеется, что вы найдете раздел функцию ПОЛЕЗНЫЕ ;-)

Смежные вопросы