Reputation: 457
I'm trying to compile the following code with g++ v.4.8.1:
#include <iostream>
#include <boost/msm/front/state_machine_def.hpp>
#include <boost/msm/front/euml/euml.hpp>
#include <boost/msm/front/functor_row.hpp>
#include <boost/msm/front/functor_row.hpp>
#include <boost/msm/back/state_machine.hpp>
typedef boost::msm::front::none none;
namespace events{
class A{
double member;
template <typename T>
struct field{
typedef T field_type;
};
public:
typedef field<double> A_double;
typedef field<float> A_float;
typedef field<int> A_int;
A() : member(M_PI){}
A(const double& d) : member(d){}
double get_member() const{ return member; }
template<typename T>
typename T::field_type extract() const{
typedef typename T::field_type ret;
return static_cast<ret>(member);
}
};
struct B{};
}
struct front : public boost::msm::front::state_machine_def<front>{
// ----------------------- States ----------------------------
struct S1 : public boost::msm::front::state<>{
template <class Event, class Fsm>
void on_entry(Event const&, Fsm& fsm) {
std::cout << "executing S1::on_entry()" << std::endl;
}
template <class Event, class Fsm>
void on_exit(Event const&, Fsm& fsm) {
std::cout << "executing S1::on_exit()" << std::endl;
}
};
struct S2 : public boost::msm::front::state<>{
template <class Event, class Fsm>
void on_entry(Event const& evt, Fsm& fsm) {
std::cout << "executing S2::on_entry()" << std::endl;
// Initialize a
fsm.a = static_cast<events::A>(evt);
}
template <class Event, class Fsm>
void on_exit(Event const&, Fsm& fsm) {
std::cout << "executing S2::on_exit()" << std::endl;
std::cout << "a.get_member(): " << fsm.a.get_member() << std::endl; // OK
int m = fsm.a.extract< events::A::A_int >(); // ERROR
std::cout << "a.extract<events::A::A_int>(): " << m << std::endl;
}
};
// --------------------------------- Initial state ------------------------------
typedef S1 initial_state;
// --------------------------------- Transition table ----------------------------------
struct transition_table : boost::mpl::vector<
// Start Event Target Action Guard
_row< S1, events::A, S2 >,
_row< S2, events::A, S2 >,
_row< S2, events::B, S1 >
> {};
template <class Fsm, class Event>
void no_transition(Event const& e, Fsm&, int state){
std::cout << "No transition found" << std::endl;
}
// Internal events::A member
events::A a;
};
typedef boost::msm::back::state_machine<front> back;
static char const* const state_names[] = { "S1", "S2" };
void pstate(back const& p){
std::cout << " -> " << state_names[p.current_state()[0]] << std::endl;
}
int main(){
back b;
events::A tmp;
std::cout << tmp.extract<events::A::A_double>() << std::endl;
b.start();
pstate(b);
std::cout << std::endl << "Firing event A()" << std::endl;
b.process_event(events::A());
pstate(b);
std::cout << std::endl << "Firing event A(153.13)" << std::endl;
b.process_event(events::A(153.13));
pstate(b);
std::cout << std::endl << "Firing event A(14)" << std::endl;
b.process_event(events::A(14));
pstate(b);
b.stop();
return 0;
}
and I get the following error:
main.cpp: In member function ‘void front::S2::on_exit(const Event&, Fsm&)’:
main.cpp:67:44: error: expected primary-expression before ‘>’ token
int m = fsm.a.extract< events::A::A_int >(); // ERROR
^
main.cpp:67:46: error: expected primary-expression before ‘)’ token
int m = fsm.a.extract< events::A::A_int >(); // ERROR
^
I've tried to substitute that line with the following one:
int m = static_cast<events::A>(fsm.a).extract<events::A::A_int>(); // OK
Now the code compiles and works as I expect.
Can someone help me to understand why?
Upvotes: 1
Views: 155
Reputation: 22981
Use
int m = fsm.a.template extract< events::A::A_int >();
Related: template member function of template class called from template function
Upvotes: 2