вызов метода из указателя функции - PullRequest
0 голосов
/ 08 мая 2019

Не могу скомпилировать с ++ 11. Я могу написать в другой форме, но я хочу этот код с исправлением только в строке ОШИБКА, или я хочу решение с нестатической функцией 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)) return EXIT_SUCCESS;

без статики: bool check2_true (const string & pattern, const string & value) {return true; }

Спасибо всем

Ответы [ 2 ]

2 голосов
/ 08 мая 2019

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;
};
0 голосов
/ 08 мая 2019

Есть две проблемы с вашим кодом (кроме отсутствующих #include s и std:: -prefixes)

Сначала вы пытаетесь использовать член класса 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...