Как я могу написать хороший шаблон для этого. Я получаю эту ошибку: «Базовый тип ссылки на элемент« void »не является структурой или объединением» - PullRequest
0 голосов
/ 17 марта 2020

Это мой код шаблона, который я пытаюсь создать. Я благодарен за некоторые предложения и советы. Это правильно или вы могли бы создать это лучше? И на самом деле я получаю это сообщение: "базовый тип ссылки на элемент 'void' не является структурой или объединением"

template <class T>
void example(QVector<T> &vec, const QString &fp, std::function<void(QFile&)> func)
{                                                /* Is this right? I don´t have to say "T" anywhere? 
Because here I would pass a method from a class(void myClass::method(QFile&) )*/

    QFile f(fp);
    if(!f.open(QIODevice::WriteOnly | QIODevice::Append) )
    {
        qDebug() << "File error" << f.error();
    }
    else
    {
        QThread::currentThread();
        for(T &tw : vec)
        {
            //tw.func(f);
            func(f).tw;  // member reference base type 'void' is not a structure or union                     
        }
    }
    f.close();
}

fun c может быть таким:

//...class definition...
//declaration of the method:
void writeTeams(QFile&);

//definition (this pass to func)
void teamType::writeTeams(QFile &f)
{
    QTextStream out(&f);
    out.setCodec("UTF-16LE");
    out << teamId << "\t" << offsideTrap << "\t" << withoutBall << "\t" << formationId << "\t"
            << attack << "\t" << teamMentality << "\t" << attackTactic1 << "\t"
            << attackTactic2 << "\t" << defenseTactic1 << "\t" << defenseTactic2 << "\t" << captain << "\t"
            << penaltyTakerId << "\t" << kickTakerId << "\t" << leftCornerkickTakerId << "\t" << rightCornerkickTakerId << "\t"
            << numTransfersIn << endl;
}

Я бы используйте шаблон в следующем коде:

...
filePath = "teamwrite.csv";
    QFuture<void> f = run(example, teams, filePath, &teamType::writeTeams); //teams came from this: QVector<teamType> teams;
...

Это правильно?

Ответы [ 2 ]

0 голосов
/ 17 марта 2020

Я думаю, это не сработает. Надо учитывать, я бы сдал член! функция к функции. И эта функция-член используется в шаблоне следующим образом:

for(T &tw : vec)
{
    tw.func(f); // I think this is correct
  //func(f).tw;     // not this                  
}

Это означает (я не уверен), что в std::function<void(int)> func мы должны сообщить, что в любом случае в этом шаблоне всегда есть класс.

0 голосов
/ 17 марта 2020

Вы передаете указатель на функцию-член (pmr), где вам нужен указатель на функцию (конструктор преобразования std::function).

Вам нужно либо объявить writeTeams как static, либо связать pmr с экземпляром teamType (невидимый первый аргумент pmr), чтобы получить std::function, который принимает один аргумент.

Давайте упростим ваш код до минимального, полного примера (поскольку материал Qt и шаблон здесь просто отвлекают):

#include <functional>

void example(std::function<void(int)> func)
{
    func(1);
}

struct teamType
{
    void writeTeams(int);
};


int main()
{
    example(&teamType::writeTeams);
}

Это не скомпилируется:

60725415.cpp: In function ‘int main()’:
60725415.cpp:19:13: error: could not convert ‘&teamType::writeTeams’ from ‘void (teamType::*)(int)’ to ‘std::function<void(int)>’
   19 |     example(&teamType::writeTeams);
      |             ^~~~~~~~~~~~~~~~~~~~~
      |             |
      |             void (teamType::*)(int)

Я могу написать (если writeTeams не нужны teamType члены):

struct teamType
{
    static void writeTeams(int);
};

Или я могу привязать к конкретному c экземпляру из teamType:

int main()
{
    using namespace std::placeholders;
    teamType the_team;
    example(std::bind(&teamType::writeTeams, the_team, _1));
}
...