Комментарий: Я отправляю этот вопрос снова, так как некоторые люди просили меня опубликовать полный код. Вот:
У меня есть указатель функции typedef, который выглядит так:
template<typename USER_DATA>
class RowProcessor
{
typedef void (*RowFunction)(USER_DATA, std::vector<USER_DATA> &);
RowProcessor(RowFunction, int) {};
};
а затем я использую в другом классе UseRowProcessor:
class UseRowProcessor {
public:
void AddUserData(SomeClass, std::vector<SomeClass> &);
void LoadUserData();
};
void UseRowProcessor::AddUserData(SomeClass c, std::vector<SomeClass> &v) {
v.push_back(c);
}
void UseRowProcessor::LoadUserData() {
RowProcessor<SomeClass> myRowProcessor(AddUserData, 1); // ERROR!!
}
Таким образом, ошибка возникает при вызове конструктора RowProcessor.
В полном сообщении об ошибке указано, что
no insatnce of constructor "RowProcessor<USER_DATA>::RowProcessor [with USER_DATA=SomeClass]" matches the argument list
argument types are: (void (SomeClass c, std::vector<SomeClass, std::allocator<SomeClass>> &v), std::vector<SomeClass, std::allocator<SomeClass>>)
о котором я не знаю, что он говорит, за исключением того факта, что аргументы конструктора не совпадают.
Почему моя AddUserFunction не соответствует указателю функции typedef??
Измените функцию:
void AddUserData(SomeClass, std::vector<SomeClass> &);
to static void AddUserData(SomeClass, std::vector<SomeClass> &);
,
Поскольку это функция-член класса, этот параметр будет добавлен после компилятора, поэтому он не является типом указателя функции. Изменяя его на статический, этот параметр не будет добавлен.
Функции членов отличаются от обычных функций, и это переносится на их тип. Существует множество рабочих обходов, которые позволяют передавать указатели на функции функций, которые принимают обычные указатели на функции в качестве их параметров, но если у вас есть контроль над кодом, вы должны пойти по другому пути. Вместо принятия указателя функции принять функтор.
template<typename Functor>
int f(Functor func) {
// use func like you would a function, e.g. call it with arguments func(1, 2)
}
Теперь вы можете называть е с лямбда, функциональный объект, член указатель функции (после того, как вы свяжете его в this
), или указатель на функцию.
Если вы хотите избежать шаблонов, вместо этого принимайте std::function
, но это нужно делать только в том случае, если у вас есть особые причины.
Поскольку Мэтт сказал, что вам нужна static
функция, чтобы получить эту работу
class UseRowProcessor {
public:
static void AddUserData(SomeClass, std::vector<SomeClass> &);
void LoadUserData();
};
Здесь полностью фиксированная выборка (после исправления static
было еще несколько проблем).