首页 > 解决方案 > (typedef) 类型名迭代器在 c++、qt 中不起作用

问题描述

我已经看到迭代器、typedef 和 typename 已经解决了很多问题。没有答案对我有帮助。

我已经尝试过没有任何东西

typename QLinkedList<T>::iterator iter = TList->begin();

typedef typename QLinkedList<T>::iterator iter = TList->begin();

整个模板:

template <class T>
void DataManager::saveObject(QLinkedList<T> * TList) {
    QFile * pFile;
    // choose a file in case of class
    if( typeid(T) == typeid(Medium) ) pFile = &fileMedium;
    else                              pFile = &filePerson;
    // open the choosen file
    pFile->open(QIODevice::WriteOnly | QIODevice::Truncate);
    // open the textSteam to write
    textStream.setDevice(&filePerson);
    // write each information to the textstream/file
    if(!TList->isEmpty())
        // set iterator                         
        typename QLinkedList<T>::iterator iter = TList->begin();
        while(iter != TList->end()) {    // <--- Err: not declared !
            textStream << iter->getDataInCSV();
            ++iter; //move iterator to next
        }
   // close the file
   pFile->close();
}

错误:

    error: 'iter' was not declared in this scope
     while(iter != TList->end()) {
           ^

标签: c++qttemplateslinked-listtypename

解决方案


  1. 您没有修改列表 - 因此通过 const 引用来获取它。您也不必担心容器的确切类型。任何与 STL 兼容的容器都可以。

  2. 使用std::is_same而不是typeid.

  3. textStream类成员始终使用该文件filePersonpFile永远不会用于任何事情。这很可能是一个错误。

  4. 使用现有文件是不正确的 - 您实际上将其用于文件名存储,并且如果保存失败,它不能保证数据不会损坏。改为使用QSaveFile

  5. 该文件存储文本数据,必须以文本模式打开。

正确的实现如下所示 - 请注意完整的签名。

#include <type_traits>

// Returns true upon success, false upon failure
template <class T> bool DataManager::saveObject(const T& data) const {
   using value_type = typename T::value_type;
   bool const isMedium = std::is_same<value_type, Medium>::value;
   bool const isPerson = std::is_same<value_type, Person>::value;
   static_assert(isMedium || isPerson,
            "The data must be of either Medium or Person type");
   const QFileDevice &aFile = isMedium ? fileMedium : filePerson;
   Q_ASSERT_X(!aFile.isOpen(), "saveObject", "The file must not be open");
   QSaveFile file(aFile.fileName());
   if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
      return false;
   {
      QTextStream stream(&file);
      for (auto &item : data)
         stream << item;
      stream.flush();
      if (stream.status() != QTextStream::Ok)
         return false;
   }
   return file.commit();
}

推荐阅读