Изменение: правильным заголовком должно быть "Вызов перегруженной истинной виртуальной функции в базовом классе", поскольку это было большой частью проблемы.
У меня есть базовый класс с реальной виртуальной функцией и несколькими другими, нормальными. Один из обычных вызывает виртуальную функцию в потоке, и я получаю ошибку в этой строке, которую я не понимаю. Я думаю, что это имеет какое-то отношение к потоку, но поскольку базовый класс является абстрактным, и каждый производный класс должен фактически реализовать виртуальную функцию, проблем не должно быть. Может быть, это нечто совершенно другое. Это более или менее то, на что похоже:
class Base {
virtual int getInfo(int a) = 0; // the culprit?
void getInfo(); // is implemented, calls getInfo(int); Does
// actually have the same name. Works perfectly fine.
void getThreadedInfo(); // for details, see below
}
// ..later..
Base::getThreadedInfo() {
...
for(int i=0; i<maxThreads; i++) {
threads.push_back(thread(getInfo, i)); // this is line 85
}
...
}
Полное сообщение об ошибке:
Error 1 error C3867: 'Base::getInfo': function call missing argument list; use '&Base::getInfo' to create a pointer to member
c:\path\to\base.cpp 85 1 Project
Error 2 error C2661: 'std::thread::thread' : no overloaded function takes 2 arguments
c:\path\to\base.cpp 85 1 Project
Вы можете использовать что-то вроде:
threads.push_back(std::thread(static_cast<int (Base::*)(int)>(&Base::getInfo), this, i));
as &Base::getInfo
неоднозначно.
У вас есть пара разных вещей.
Первый, самый простой для исправления - это то, о чем вам сообщает первое сообщение об ошибке - вам нужно использовать оператор &
с getInfo
аргументов getInfo
в thread
для создания указателя функции.
Вторая проблема заключается в том, что вызов getInfo
в getInfo
thread
требует дополнительного аргумента. В дополнение к явному int a
, поскольку getInfo
не является статическим, он принимает неявное значение Base* this
. Поэтому this
нужно добавить.
Третья, самая сложная проблема заключается в том, что Base
имеет две перегрузки getInfo
, поэтому вам нужно сделать ее явной, какой вы хотите.
Соединяя все три вещи вместе, вы должны иметь... точно, что сказал этот ответ, когда я печатал. :)
this
, как компилятор узнает, на каком объекте Base
вы хотите вызвать getInfo
? Когда вы вызываете функцию обычным способом с чем-то вроде o.getInfo(3)
, очевидно, что объект слева от оператора должен использоваться как this
. Но когда вы используете функцию в общем, вы должны предоставить значение для this
явно.