получение обязательного (указатель на) функционального типа для переменной, определенной как (указатель на) функциональный тип - PullRequest
0 голосов
/ 28 апреля 2011

Я создаю typedef для функции, которая будет использоваться для вызова произвольных функций, которые хранятся в строке для отображения указателя на функцию.Я уверен, что проблема как-то связана с тем, как тип объявляется и на который ссылаются многие объекты в моем коде, но это единственный способ, который я могу придумать, как сделать то, что мне нужно

Это fmap.h здесь я объявляю класс fmap и класс executefunctions, typedef для указателя функции находится в первой строке открытых членов для fmap

class Web;
class Matlab;
class Word;
class Node;

class ExecFunctions
{
public:
    ExecFunctions(){}
    /**
    Function:       travel
    */
    int travel(Web *concepts, Matlab *mat, Word * words, int reqIdx, string theWord, vector<string> *dependsMet);

};

class FMap
{
public:
    typedef int (ExecFunctions::*ExecFunc)(Web *, Matlab *, Word *, int, string, vector<string> *);
    ExecFunc getFunc(string funcName){
        return theFuncMap.descrToFuncMap[funcName];
    }

private:
    class FuncMap {
    public:
        FuncMap() {
                descrToFuncMap["travel"] = &ExecFunctions::travel;  
        }
        std::map<std::string, ExecFunc> descrToFuncMap;
    };    
};



#endif

далее - web.h Я включаю только то, чтоЯ думаю, что соответствующие части

#include "fmap.h"

class Node
{
    private:
        ....
        //pointer to execcution function
        FMap::ExecFunc func;
        //fmap function used to access execution function pointers
        FMap *functionMap;
            .....    
public:
          FMap::ExecFunc getExecFunc();
};

теперь то, что я считаю соответствующей частью web.cpp

Node::Node(string name, Node *nodeParent)
{
    attrList = new Attr();
    nodeName = name;
        ........
    func = functionMap->getFunc(name);
}

Теперь, наконец.Вот где я получаю ошибку.Перед строкой ошибки есть три строки комментариев, объясняющих полученную мной ошибку.

void process(Util myUtil, Web *concepts, Matlab *mat, string path)
{
    int funcP
    bool dependsProcessed = false;
    vector<string> *dependsDone = new vector<string>();
    FMap::ExecFunc funcToCall;

    funcToCall = realMeanings[i][j]->getConcept()->getExecFunc();


//the line bellow this comment is where I'm getting the error. Visual Studio says
//that funcToCall must have (pointer-to) function type, and then the VS compiler says
//diabot.cpp(177): error C2064: term does not evaluate to a function taking 6 arguments
    funcPtrRet = funcToCall(concepts, mat, realMeanings[i][j], reqConceptsIdx[i][j], queryWords[i], dependsDone);

    return;
}

любая помощь, которую кто-либо может оказать, будет принята с благодарностью.

Заранее всем спасибо

Ответы [ 3 ]

0 голосов
/ 28 апреля 2011

Ваш funcToCall является указателем на функцию-член, но вы вызываете как простой указатель на функцию, вам нужно вызвать его для экземпляра класса ExecFunctions, в противном случае рассмотрите возможность изменения ExecFunctions на пространство имени ExecFunc до int ()(Web *, Matlab *, Word *, int, string, vector<string> *);

0 голосов
/ 28 апреля 2011

Проблема в том, что функции-члены и свободные функции различаются в C ++, и если вы подумаете об этом, есть веская причина (скрытый неявный аргумент this).Существуют различные решения для того, что вы хотите сделать, в зависимости от того, что вам действительно нужно:

Низкий уровень:

  • Отключить функции (переместить их на уровень пространства имен).
  • Сделайте функции статичными (удаляет скрытые this, и тогда это определение типа сработает. Сначала рассмотрим первый вариант, C ++ не заставляет вас добавлять весь код внутри классов, а иногда функции не принадлежаткласс. Нет смысла создавать бессмысленный класс только для хранения некоторых свободных функций.
  • Измените typedef, чтобы отразить, что они являются членами: typedef return_type (type::*member_function)( arg_type ); - но это потребует создания typeобъект для вызова функции-члена.

Высокий уровень:

  • использование std::function (C ++ 0x) или boost::function вместе с bind: thisявляется наиболее гибким, так как он позволит вам bind не только свободные функции и статические функции, но и функции-члены, предоставляя реальный объект. Но: если вам не нужна гибкость, вы можете использовать один издругие варианты.
0 голосов
/ 28 апреля 2011

Я не уверен, что не заблудился, читая весь код, но я считаю, что вы должны вызывать funcToCall() для экземпляра ExecFunctions, потому что ExecFunc является типом указателя на метод.

Что это дает, если вы используете следующий синтаксис:

ExecFunctions ef;
ef.*funcToCall(...);

или

ExecFunctions* ef = ...;
ef->*funcToCall(...);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...