我正在将代码从Red Hat Enterprise Linux ES版本3的服务器迁移到Red Hat Enterprise Linux 7.5版本的服务器。该代码可以在RH 3盒(带有gcc 3.2.3)上成功编译,但是不能在RH 7.5盒(带有gcc 4.8.5)上成功编译。这是有问题的头文件代码:
#ifndef FSM_H
#define FSM_H
#include <assert.h>
#include <string>
#include <map>
namespace fsm {
template<class A>
class Event {
bool (A::*Action)(void); // Action to peform. False means it failed.
std::string gotoState; // State to transition on success
public:
Event();
Event( const Event &rhs );
Event( bool (A::*Action)(void), const std::string &newState );
const std::string HandleEvent(A *parent) const;
};
template<class A>
class State : protected std::multimap<const std::string,Event<A> > {
public:
void addEvent( const std::string &event,
bool (A::*Action)(void),
const std::string &newState);
const std::string HandleEvent( A *parent, const std::string &event ) const;
};
template<class A>
void State<A>::addEvent(const std::string &event,
bool (A::*Action)(void),
const std::string &newState )
{
insert(State<A>::value_type(event,Event<A>( Action, newState )));
}
template<class A>
const std::string State<A>::HandleEvent( A *parent, const std::string &event ) const
{
typename State<A>::const_iterator i;
std::string newState;
for( i=lower_bound(event); i!=upper_bound(event); i++ ) {
newState = i->second.HandleEvent(parent);
if ( newState.size() ) return newState;
}
return std::string();
}
} // namespace fsm
#endif
编译器抱怨insert
,lower_bound
和upper_bound
函数;它找不到这些功能中的每一个的匹配功能。这些应该解释为属于std::map
的函数,但是编译器似乎正在尝试使用std::upper_bound
和std::lower_bound
(我不确定insert
的编译器函数是什么)正在尝试使用)。
为了使编译器一目了然,我修改了代码,以确保lower_bound
,upper_bound
和insert
是std::map
函数。例如,在这段代码中:
template<class A>
const std::string State<A>::HandleEvent( A *parent, const std::string &event ) const
{
typename State<A>::const_iterator i;
std::string newState;
for( i=lower_bound(event); i!=upper_bound(event); i++ ) {
newState = i->second.HandleEvent(parent);
if ( newState.size() ) return newState;
}
return std::string();
}
我将代码修改如下:
template<class A>
const std::string State<A>::HandleEvent( A *parent, const std::string &event ) const
{
typename State<A>::const_iterator i;
typename State<A>::const_iterator lowerBound;
typename State<A>::const_iterator upperBound;
std::string newState;
lowerBound = std::multimap<const std::string, fsm::Event<A>, std::less<const std::string>,
std::allocator<std::pair<const std::string, fsm::Event<A> > > >::lower_bound(event);
upperBound = std::multimap<const std::string, fsm::Event<A>, std::less<const std::string>,
std::allocator<std::pair<const std::string, fsm::Event<A> > > >::upper_bound(event);
for( i=lowerBound; i!=upperBound; i++ ) {
newState = i->second.HandleEvent(parent);
if ( newState.size() ) return newState;
}
return std::string();
}
那行得通,但这是胡扯,冗长而丑陋的。有没有更好的方法来帮助编译器知道它应该使用std::map
中的函数,而不必以这种乏味的方式将其拼写出来?