从函数指针调用方法

时间:2019-05-08 12:58:15

标签: c++ function-pointers

我无法使用c ++ 11进行编译。我可以用另一种形式编写,但是我只需要在ERROR行上对此代码进行更正,或者我想要一个具有非静态check2函数的解决方案。

#include <functional>
#include <string>
#include <vector>
using namespace std;
class If {
            public:
                struct Command {
                    string pattern;
                    bool (If::*check)(const string&, const string&);
                    function<bool(const string&, const string&)> check2;
                };
                If() {
                        Command command;
                        command.check = &If::check_true;
                        command.check2 = this->check2_true;
                        m_commands.push_back(command);
                }
                int modify() {
                    string result;
                    for (auto i = m_commands.begin(), end = m_commands.end(); i != end; ++i) {
                        if (((i)->*(Command::check))(i->pattern, result)) return EXIT_SUCCESS; // ERROR
                        if (this->*(i->check2)(i->pattern, result)) return EXIT_SUCCESS; // OK but i don't wont static function
                    }
                    return EXIT_FAILURE;
                }
                bool check_true(const string& pattern, const string& value) { return true; }
                static bool check2_true(const string& pattern, const string& value) { return true; }
            private:
                vector<Command> m_commands;
        };

错误:      if((((i)-> *(Command :: check))(i-> pattern,result))返回EXIT_SUCCESS;

无静态:      bool check2_true(const string&pattern,const string&value){返回true; }

谢谢

2 个答案:

答案 0 :(得分:2)

check不是Command的静态成员-它是*i的成员-因此,您应该使用普通的成员访问语法i->check
另外,可以调用成员函数的If实例是*this

(this->*(i->check))(i->pattern, result)

请注意,(this->*(i->check))中的外部括号不是必需的,而内部括号不是必需的,但是我认为内部括号使它更具可读性。

您可以使用类型别名,函数和范围循环进一步提高可读性:

class If
{
public:
    using CommandFunction = bool (If::*)(const string&, const string&);
    // Alternative: typedef bool (If::*CommandFunction)(const string&, const string&);
    struct Command {
        string pattern;
        CommandFunction check;
    };
    If() {
        Command command;
        command.check = &If::check_true;
        m_commands.push_back(command);
    }
    bool call(CommandFunction f, const string& a, const string& b)
    {
        return (this->*f)(a, b);
    }
    int modify() {
        string result;
        for (const auto& i: m_commands) {
            if (call(i.check, i.pattern, result)) 
                return EXIT_SUCCESS;
        }
        return EXIT_FAILURE;
    }
    bool check_true(const string& pattern, const string& value) { return true; }
private:
    vector<Command> m_commands;
};

答案 1 :(得分:0)

您的代码有两个问题(除了缺少的#includestd::前缀之外)

首先,您尝试使用类成员Command::check,但是(可能)有多个Command对象,每个对象都有自己的check成员。您必须指定要访问的Command对象。

由于您正在使用Command迭代器遍历i对象的向量,因此我假设您想访问check-member所引用的i。像这样:i->check

第二个:check指向方法check_true,它是类If的成员。这意味着在调用check_true时,您还必须指定方法应作用于哪个If对象(成员check不包含该信息)

通常,这意味着当直接调用check_true时,您可以这样做:

a.check_true(..) // `a` is of type `class If`

或     b-> check_true(..)// b的类型为class If *

当通过函数指针(在您的情况下为i->check)间接执行此操作时,您将执行以下操作:

a.*(i->check)(...) // `a` is of type `class If`

b->*(i->check)(...) // `b` is of type `class If *`

但是您这样称呼它:

(i)->*.... 

i不是指向If对象的指针,而是对Command对象的引用。

由于您是在If::modify()中进行所有操作,因此我还假设(i->check)(..)应该对与If当前正在作用的同一modify()对象起作用。因此,更正后的函数调用应为:

this->*(i->check)(i->pattern, result)