2013-04-05 4 views
3

В настоящее время я пишу код для игры, и часть этого включает в себя создание истории действий, которые произошли до сих пор в игре. Эта история хранится в векторе парных действий state_pair_t (action_t) и указывает на результат игры после того, как было сделано действие. Теперь у меня есть некоторая функция, которая просматривает историю, начиная с самого последнего момента времени и итерации назад, пока не будет найдено действие определенного типа, а затем вернет ссылку на это. Теперь мы решили, что может быть хорошим шагом в проекте, чтобы использовать boost, чтобы вернуть no_action, если не было найдено никаких действий, и используйте boost::optional для решения этих функций, которые должны возвращать значение, но которое может не иметь возвращаемого значения. Когда я на самом деле пытался осуществить это я бегу в ошибку, что я не понимаю:boost :: необязательная ссылка с boost :: variant type

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

Теперь это дает ошибку компиляции:

Error error C2664: 'boost::optional<T>::optional(boost::none_t)' : cannot convert parameter 1 from 'const action_t' to 'boost::none_t' 

Теперь, если я изменить это немного:

if(!(is_action_type<A>(rcit->first))){ 
     return boost::optional<action_t>(rcit->first); 
    } 

я получаю другую ошибку:

error C2664: 'boost::optional<T>::optional(boost::none_t)' : cannot convert parameter 1 from 'boost::optional<T>' to 'boost::none_t' 

Я не уверен, что одна из этих ошибок пытается рассказать мне об этом. Является ли то, что я пытаюсь сделать здесь, не очень хорошая идея с boost::optional? Возможно ли это?

ответ

2

Дополнительные ссылки сами по себе являются хорошей идеей; они конкретно упоминаются как таковые в recent paper n3527, предназначенные для стандартизации в качестве компонента библиотеки в C++ 14. Они поддерживаются в Boost.Optional.

Проблема с вашим кодом заключается в том, что вы пытаетесь связать необязательную ссылку не const со значением const lvalue; если вы измените boost::optional< action_t& > на boost::optional< const action_t& >, он должен скомпилировать штраф.

+0

Спасибо за этот ответ. Кажется, что это почти делает его компиляцией правильно, но теперь я столкнулся с проблемой, когда компилятор жалуется, что 'T = opt_action_ref_t' не является частью типа варианта action_t. Я нахожу это немного странным, потому что я не хочу, чтобы 'opt_action_ref_t' был типом в варианте вообще. Я что-то явно делаю неправильно? – shuttle87