Question

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?

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top