I am trying to find a way to specify a hierarchy of *implicit* conversions between different types.

Suppose I have two types and a function overload for each:

```
struct A{};
struct B{};

void f(A const& a){}
void f(B const& b){}

```

Now I have another class that it is implicitly convertible to both `A` and `B`

```
class C{
    A to_A()  const{return A{} ;}
    B to_B() const{return B{};}
    operator A() const{return to_A() ;}
    operator B() const{return to_B();}
};

```

As it is, I cannot use `f` directly because of ambiguity.

```
int main(){
    C c;
    f(c); // ambiguous, convert c to a, o c to b??
}

```

Let's also say that a conversion to `B` is more sensible given the option.

**Is there way to specify in `struct C` one of the two (`A` or `B`) as the preferred conversion?**, so that `main` compiles and is equivalent to `f(c.to_B());`

Full code here: <https://godbolt.org/z/xvz71qEhK>

Possible near solutions I discarded:

1. One obvious way is to make one conversions (to `A`) `explicit`, but I want that both conversion are implicit. Because there are other functions (not overloaded like `f`) where both conversion can be implicit.
2. At the place of call make the conversion explicit, `main(){f(c.to_B());}` The problem is that I am using this in generic template functions where the template parameter can be `A`, `B` or `C`.
3. For every ambiguous overload make a new overload `f(C const& c){return f(c.to_B());}`, the problem is that I have to do this for every overloaded functions that can take `A` or `B` and I have many of them. I can have tens of `f`-like functions, some of them with more than one argument (exploding number of combinations).

---

What I tried so far: I though that defining a hierarchy would help to select the *preferred* conversion, and that the operators of the leaf class would have preference, but it didn't remove de ambiguity.

<https://godbolt.org/z/fYj7PP5GE>

```
template<class CRTP>
struct base_to_A{
    operator A()  const{
        return static_cast<CRTP const&>(*this).to_A() ;
    }
};

class C : public base_to_A<C>{
    A to_A() const{return A{};}
    B to_B() const{return B{};}
public:
    operator B() const{return to_B();}
};

```

Playing with `public/protected/private` didn't help.