Шаблоны и Массив структур, которые содержат указатель на метод в классе - PullRequest
0 голосов
/ 21 ноября 2018

Я пытаюсь создать класс, который определяет массив командных структур, каждая из которых имеет две переменные CHAR, одну CHAR *, одну INT и указатель на функцию void, которая принимает два аргумента CHAR.Там будет несколько экземпляров этого массива, каждый в своем классе.Я чувствую, что я рядом, но упускаю что-то критическое.Компилятор Arduino GNU, похоже, согласен с тем, что мне чего-то не хватает.Вот код (с изменениями в соответствии с Bo R);

<<<<<<<<<< Commands.h >>>>>>>>>>>>>>>>>

#pragma once
//template <class T>
class Commands {
public:
    typedef void ( Commands::*FunctionPointer )( char, char );

    struct command {
        char sel;
        char act;
        char const *desc;
        FunctionPointer funcPtr;
    };

    command myCommands [2] = {
        command { 'a','?',"FOO", &Commands::foo },
        command { 'b','x',"BAR", &Commands::bar },
    };

    int cmdSize = sizeof ( myCommands ) / sizeof ( myCommands [0] );

    void foo ( char sel, char act ) {
        show ( { sel }, { act } );
    }

    void bar ( char sel, char act ) {
        show ( { sel }, { act } );
    }

    void show ( char sel, char act ) {
        Serial.print ( "SEL = " );
        Serial.print ( sel );
        Serial.print ( " ACT = " );
        Serial.println ( act );
    }

    void execute ( char sel, char act ) {
        for (int i = 0; i < cmdSize; i++) {
            if (myCommands [i].sel == sel && myCommands [i].act == act) {
                Serial.println ( myCommands [i].desc );
                ( this->*myCommands [i].funcPtr )( sel, act );
                return;
            }
        }
        Serial.print ( F ( "Unknown SEL/ACT Pair:" ) );
        Serial.print ( sel );
        Serial.print ( '/' );
        Serial.println ( act );
    }
};


<<<<<<<<<< StructArray.ino >>>>>>>>>>>>>>>>>

#include "Commands.h"    
Commands cmd;
void setup() {
    Serial.begin ( 115200 );
    Serial.println ( "EXECUTING:" );
    cmd.execute ( 'a', '?' );
    cmd.execute ( 'b', '?' );
    cmd.execute ( 'b', 'x' );
    Serial.println ( "DONE" );
}

void loop(){}

Если я произвожу рефакторинг команд в Template.h и Foo.h (как показано ниже), я получу четыре ошибки компиляции, которые я не понимаю, какисправить:

Код серьезности Описание Строка файла Ошибка Ошибка: недопустимое использование имени шаблона «Шаблон» без списка аргументов D: \ Documents \ Arduino \ StructArray \ Foo.h 6 Ошибка ошибки: «myCommands» былне объявлено в этой области D: \ Documents \ Arduino \ StructArray \ Foo.h 11 Ошибка: в этой области не было объявлено «myCommands» D: \ Documents \ Arduino \ StructArray \ Foo.h 11 Ошибка: неверное использование шаблонаимя Foo без списка аргументов D: \ Documents \ Arduino \ StructArray \ StructArray.ino 7

Вот код для Template.h:

#pragma once
template <class T>
class Template {
public:
    typedef void ( T::*FunctionPointer )( char, char );

    struct command {
        char sel;
        char act;
        char const *desc;
        FunctionPointer funcPtr;
    };

    void show ( char sel, char act ) {
        Serial.print ( "SEL = " );
        Serial.print ( sel );
        Serial.print ( " ACT = " );
        Serial.println ( act );
    }

    void execute ( char sel, char act, int cmdSize ) {
        for (int i = 0; i < cmdSize; i++) {
            if (T::myCommands[i].sel == sel && T::myCommands [i].act == act) {
                Serial.println ( T::myCommands [i].desc );
                ( this->*T::myCommands [i].funcPtr )( sel, act );
                return;
            }
        }
        Serial.print ( F ( "Unknown SEL/ACT Pair:" ) );
        Serial.print ( sel );
        Serial.print ( '/' );
        Serial.println ( act );
    }
};

И Foo.h:

#pragma once
#include "Template.h"
template<class T>
class Foo {
public:
    Template::command myCommands [2] = {
    command { 'a','?',"FOO-A", &Foo::foo },
    command { 'b','x',"FOO-B", &Foo::bar },
    };

    int cmdSize = sizeof ( myCommands ) / sizeof ( myCommands [0] );


    void foo ( char sel, char act ) {
        show ( { sel }, { act } );
    }

    void bar ( char sel, char act ) {
        show ( { sel }, { act } );
    }
};

1 Ответ

0 голосов
/ 21 ноября 2018

Если я начну вас с версии без шаблонов, вы увидите, что вам нужно внести некоторые изменения.

class Commands {
public:
    typedef void ( Commands::*FunctionPointer )( char, char );

    struct command {
        char sel;
        char act;
        char const *desc;
        FunctionPointer funcPtr;
    };

    command myCommands [2] = {
            { 'a','?',"FOO", &Commands::foo },
            { 'b','x',"BAR", &Commands::bar }
    };

    int cmdSize = sizeof ( this->myCommands ) / sizeof ( this->myCommands [0] );

    void foo ( char sel, char act ) {
        char buf[2] = {sel};
        Serial.println ( buf );
    }

    void bar ( char sel, char act ) {
        char buf[2] = { sel };
        Serial.println ( buf );
    }

    void execute ( char sel, char act ) {
        for (int i = 0; i < cmdSize; i++) {
            if (myCommands [i].sel == sel && myCommands [i].act == act) {
                Serial.println ( myCommands [i].desc );
                (this->*myCommands [i].funcPtr)( sel, act );
            }
        }
    }

};

Как только это будет решено, вы можете атаковать шаблон (что я не сделалсмотрите цель прямо сейчас в этом примере, так как foo и bar были частью класса шаблона.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...