Replace:
tokens.erase(std::remove_if(tokens.begin(), tokens.end(), *fi), tokens.end());
with:
tokens.erase(std::remove_if(tokens.begin(), tokens.end(), std::ref(*fi)), tokens.end());
remove_if
takes its functor by-value, which causes your *fi
to be sliced into an instance of the base class, which has a pure virtual
object. Things go poorly.
std::ref
has an overloaded operator()
which should invoke the virtual operator()
of *fi
if MSVC didn't screw things up (for example, if it invokes the operator the wrong way).
If this fails, you can write your own adapter:
template<typename T>
struct callable_by_ref {
T* t;
template<typename... Args>
auto operator(Args&&...args) const ->
decltype( std::declval<T&>()(std::declval<Args&&>()...) )
{
return (*t)(std::forward<Args>(args)...);
}
};
template<typename T>
callable_by_ref< typename std::remove_reference<T>::type >
call_by_ref( T&& t ) {
return {&t};
}
which should solve your problem even if std::ref
does not.
tokens.erase(std::remove_if(tokens.begin(), tokens.end(), call_by_ref(*fi)), tokens.end());
What I am doing:
The callable_by_ref
is basically a quick perfect forwarder with a half-functional std::reference_wrapper
implementation on top of it. call_by_ref
does type deduction for you to create such an object.