You have const
problem here.
You are passing not const object to apply_visitor
- so not const object members are passed to applied visitor. So in your case it is string&
- reference to string type. This template is exact match for it:
template<typename T>
bool operator()(T &other) const
So it is selected. This function is not exact match - it is skipped:
bool operator()(const string &other) const
Of course if you provide that operator:
bool operator()(string &other) const
then it would be selected, since non template function are considered before template one.
So solution is: either provide method in your visitor which takes string reference (not const) - or pass const variant to apply...
First solution - remove const from string operator:
bool operator()(/*const*/ string &other) const
// ^^^^^^^^^ remove it
Second solution - pass const object:
const MyVariant& cv = v;
apply_visitor(StartsWith("123"), cv);
// ^^ const object passed here
Third solution - add const specifier to general visitor:
template<typename T>
bool operator()(const T &other) const
// ^^^^^
Solutions 1st and 3rd are the better than 2nd - you should pass consistent visitor to your variant, const has strong meaning when compiler has to select appropriate function.