I'm currently writing some code for a game and part of that involves creating a history of the actions that have taken place so far in the game. This history is stored in a vector of state_pair_t
's pairs of actions (action_t
's) and pointers to the result gamestate after an action has been made. Now I have a some function that looks through the history starting at the most recent point in time and iterates backwards until an action of a certain type is found then returns a reference to that. Now we decided that it might be a good design move to use boost optional to return a no_action
if no action was found and use boost::optional
to deal with these functions which should return a value but which might not have a value to return. When I've actually tried to implement this I run into an error that I don't understand:
typedef boost::variant<
A,
B,
B
> action_t;
typedef boost::optional< action_t& > opt_action_ref_t;
const opt_action_ref_t no_action = opt_action_ref_t();
/*! A state pair is the combination of a particular action and the resulting game state */
typedef std::pair< const action_t, game_state_ptr > state_pair_t;
opt_action_ref_t get_last_non_A_action() const{
std::vector< state_pair_t >::const_reverse_iterator rcit;
for(rcit = m_states.rbegin(); m_states.rend() != rcit ; ++rcit){
if(!(is_action_type< A >(rcit->first))){
return rcit->first; \\error at compile time
}
}
return no_action;
}
Now this gives a compile error:
Error error C2664: 'boost::optional<T>::optional(boost::none_t)' : cannot convert parameter 1 from 'const action_t' to 'boost::none_t'
Now if I change this slightly to:
if(!(is_action_type< A >(rcit->first))){
return boost::optional<action_t>(rcit->first);
}
I get another error:
error C2664: 'boost::optional<T>::optional(boost::none_t)' : cannot convert parameter 1 from 'boost::optional<T>' to 'boost::none_t'
I'm not sure what either of these errors are trying to tell me here. Is what I'm trying to do here not a good a good idea with boost::optional
? Is it even possible?
Optional references are in themselves a good idea; they're specifically mentioned as such in the recent paper n3527, intended for standardisation as a library component in C++14. They're supported in Boost.Optional.
The problem with your code is that you're trying to bind a non-const optional reference to a const lvalue; if you change boost::optional< action_t& >
to boost::optional< const action_t& >
it should compile fine.