Search code examples
c++pointersboost-iteratorstemplate-function

C++ template function with pointer argument taken from iterator gives error


I am sorry if the title was not descriptive enough, I have no idea what is wrong with this:

  template <class S, class P> 
  P* findPolicy(boost::ptr_vector<P> &policies,S *state)
  {
    typename boost::ptr_vector<P>::iterator it;
    for ( it = policies.begin(); it != policies.end(); ++it)
    {
      if ( *it->getState() == state)
      {
        return &(*it);
      }
    }
  }

When I call the above function from within the following member function:

template <class S> template <class P>
void Policy<S>::updateOptimal(boost::ptr_vector<P> &policies)
{
  S *curr_state = state;
  boost::ptr_vector<Action> actions = curr_state->getAllActions();
  P *best_pol;
  boost::ptr_vector<Action>::iterator iter;
  for (iter = actions.begin(); iter != actions.end(); ++iter)
  {
    if (iter->getNextState())
    {
      S *s = dynamic_cast<S *>(iter->getNextState());
      P *temp_pol = var::findPolicy<S,P>(policies,s);
      if (temp_pol->getValue() > best_pol->getValue())
      {
        opt_Action = &(*iter);
      }
    }
  }  
}

I always get: policy.hpp:237: error: no matching function for call to 'findPolicy(boost::ptr_vector<Greedy<guState>, boost::heap_clone_allocator, std::allocator<void*> >&, State*&)


Solution

  • It can't deduce the template argument for S and P however since you explicitly call the method with arguments you're skipping deduction and so the compiler is simply telling you it can't find that specific match.

    The most likely reason it can't find it is because either S or P are templates and not actual types. If so then you need to specify that by adding a typename in front of them. Try this instead:

    P *temp_pol = var::findPolicy<typename S, typename P>(policies, s);
    

    Also note the the following was probably a typo:

    template <class S> template <class P>
    void Policy<S>::updateOptimal(boost::ptr_vector<P> &policies)
    

    should probably be:

    template <class S, class P>
    void Policy<S>::updateOptimal(boost::ptr_vector<P> &policies)
    

    Edit: Also noticed a strange use of a previous parameter you are specifying P in your function but passing a boost::ptr_vector<P>& into it and apparently your template arguments and function parameters are not in the same order as you have <S, P> then pass them in as (policies, s). Try to avoid confusing or misleading code like this.

    I'm assuming you didn't write this as you don't have a specific question so this may also fall under don't use something you don't understand as well. There are probably other issues as yet undiscovered and you may be better off going back to the drawing board and coming up with a design that works that is maintainable for you.