可变参数模板和模板类

时间:2019-04-04 09:22:32

标签: c++

我正在尝试为StateMachine建立某种过渡表。我对模板很陌生。所以,如果我犯了一个愚蠢的错误,请原谅我。

这是我的Transitiontable类的代码:.cpp和.h

template<typename T, typename ...Arg>
class TransitionTable
{
public:

    TransitionTable(T first, Arg... rest);
    ~TransitionTable();
};

template <typename T, typename ... Arg>
TransitionTable<T, Arg...>::TransitionTable(T first, Arg... rest) {
    std::cout << "New Transition Table" << std::endl;
    std::unique_ptr<T> Test = new T;
    TransitionTable(rest...);
}

template <typename T, typename ... Arg>
TransitionTable<T, Arg...>::~TransitionTable() {}

这是我的Main():

int main() {

    TransitionTable
        <
        State1, State2, Event1,
        State1, State3, Event2,
        State2, State3, Event1,
        State2, State1, Event2,
        State3, State1, Event1,
        State3, State2, Event2

        > test(State1, State2, Event1,
            State1, State3, Event2,
            State2, State3, Event1,
            State2, State1, Event2,
            State3, State1, Event1,
            State3, State2, Event2);


    return 0;
}

因此,我尝试使用该唯一指针再次创建一个新州并立即删除该新州。这仅是为了我试图了解有关可变参数模板的更多信息。 StateClasses Con和Destruktor里面都有一个提示,说明他们是自己建造还是删除自己。

StateClass的示例。它们看起来都一样:

public:
    State1(){
        std::cout << "State1 erstellt! " << m_Name << "\n";
    }

    virtual ~State1() {
        std::cout << "State1 zerstoert! " << m_Name << "\n";
    }

    void Entry() override {
        std::cout << "Entry State1!\n";
    }

    void Exit() override {
        std::cout << "Exit State1!\n";
    }

private:
    std::string m_Name;
};

我现在的问题是,它基本上什么也不做。.有人可以告诉我为什么吗?如果我一开始就设置了断点,则调试器甚至不会打开。

问候和感谢!

编辑:

状态机.cpp



StateMachine::StateMachine(): m_InitState(m_CurrentState) {}

StateMachine::StateMachine(std::string na, trans_map trans, AbstractState* init): m_Name(na),
                                                                                  m_InitState(init),
                                                                                  m_TransitionTable(trans) {}

StateMachine::~StateMachine() = default;

void StateMachine::Start() {
    m_CurrentState = m_InitState;
    std::cout << "Zustandsmachine gestartet!\n";
    m_CurrentState->Entry();
}

void StateMachine::Stop() {
    m_CurrentState->Exit();
    m_CurrentState = nullptr;
    std::cout << "Zustandsmachine gestoppt!\n";
}

void StateMachine::HandleEvent(AbstractEvent* ev) {

    for(auto outer_map : m_TransitionTable) {
        if(outer_map.first == m_CurrentState) {
            if(outer_map.second.find(ev)->second)
                m_NextState = outer_map.second.find(ev)->second;
        }
    }
    if (m_CurrentState != m_NextState)
        Transition();
}


void StateMachine::Transition() {

    m_CurrentState->Exit();
    m_NextState->Entry();
    m_CurrentState = m_NextState;

}

void StateMachine::SetInitState(AbstractState* init) {
    m_InitState = init;
}

void StateMachine::CreateTransitionTable(const trans_map& transition) {
    m_TransitionTable = transition;
}

AbstractState* StateMachine::GetCurrentState() const {
    return m_CurrentState;
}

状态机.h

#pragma once
#include <map>
#include <string>
#include <iostream>
#include "AbstractState.h"
#include "AbstractEvent.h"



typedef std::map<AbstractEvent*, AbstractState* > trans_map_inner;
typedef std::map<AbstractState*, trans_map_inner> trans_map;



class StateMachine{
public:

    StateMachine();
    StateMachine(std::string na, trans_map trans, AbstractState* init);
    ~StateMachine();

    void Start();

    void Stop();

    void HandleEvent(AbstractEvent* ev);


    void Transition();

    void SetInitState(AbstractState* init);

    void CreateTransitionTable(const trans_map& transition);

    AbstractState* GetCurrentState() const;
private:
    std::string m_Name;
    AbstractState* m_CurrentState = nullptr;
    AbstractState* m_NextState = nullptr;
    AbstractState* m_InitState;
    trans_map m_TransitionTable;

};

Abstractstate和Abstactevent类只是小的AbstractClasses。

1 个答案:

答案 0 :(得分:2)

问题是这个

TransitionTable
    <
    State1, State2, Event1,
    State1, State3, Event2,
    State2, State3, Event1,
    State2, State1, Event2,
    State3, State1, Event1,
    State3, State2, Event2

    > test(State1, State2, Event1,
        State1, State3, Event2,
        State2, State3, Event1,
        State2, State1, Event2,
        State3, State1, Event1,
        State3, State2, Event2);

不会像您想象的那样调用构造函数。您所写的是函数的声明,该函数返回TransitionTable<State1, State2, …>并接受类型为State1, State2, …的参数。因此,您的代码实际上除了声明一个函数并返回0之外没有执行任何操作。这也称为Most Vexing Parse。如果希望将其作为构造函数调用,则必须创建State1, State2, …类型的对象,并将其作为参数提供给构造函数。 State1, State2, …不是函数调用参数的列表,而是类型的列表...