简体   繁体   中英

Variadic Templates and Template Classes

I am trying to build some kind of Transitiontable for a StateMachine. I am pretty new to templates. So please forgive me if i made a stupid mistake.

This is my code for the Transitiontable class: .cpp and .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() {}

This is my 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;
}

So i am trying to create a new State and delete the new State right after again with that unique Pointer. This is just for me trying to understand more about Variadic Templates. The StateClasses Con and Destruktor all got a cout within them which say if they build or deleted themselfs.

Example for a StateClass. They all look the same:

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;
};

My Problem now is that it's basicly doing nothing.. Can someone tell me please why? If I set a Breakpoint right at the start, the Debugger never even opens up.

Greetings and thanks for help!

Edit:

Statemachine .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;
}

Statemachine .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;

};

The Abstractstate and Abstactevent class are just small AbstractClasses.

The Problem is that this

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);

does not call the constructor as you may think. What you've written there is the declaration of a function that returns a TransitionTable<State1, State2, …> and takes parameters of types State1, State2, … . So your code does indeed not do anything except declare a function and return 0. This is also known as the Most Vexing Parse . If you wanted this to be a constructor call, you'd have to create objects of types State1, State2, … and provide those as arguments to the constructor. State1, State2, … is not a list of function call arguments, it's a list of types…

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM