I am defining a `DoubleWrapper`

class inheriting from two CRTP base classes, `Ratioable`

and `Divable`

, that both define `operator/()`

, with different signatures:

```
T operator/(double const& scalar) const { return T(this->underlying().get() / scalar); }
double operator/(T const& other) const { return this->underlying().get() / other.get(); }
```

They differ both by return type and parameter type. However compiler is complaining about operator/() being ambiguous. Note that the constructor is explicit so there is no ambiguous conversion from double to DoubleWrapper.

- On Visual Studio 2017 it is compiling and running fine however I get a tooltip in the code "more than one operator "/" matches those operands: (...)" at the place of use. If I rename the operator to make it a regular method (
`divide`

(...)), I get a compile error :

error C2385: ambiguous access of 'divide' note: could be the 'divide' in base 'Divable' note: or could be the 'divide' in base 'Ratioable'

G++ 6.2 gives me a compile error even with the operator version:

error: request for member ‘operator/’ is ambiguous double b = a / a; ^ note: candidates are: double Ratioable::operator/(const T&) const [with T = DoubleWrapper] double operator/(T const& val) const { return this->underlying().get() / val.get(); } ^~~~~~~~ note: T Divable::operator/(const double&) const [with T = DoubleWrapper] T operator/(double const& val) const { return T(this->underlying().get()/ val); } ^~~~~~~~

C++ allows methods with the same name as long as they have different signatures. Where is the ambiguity coming from ?

Test code:

```
DoubleWrapper a(10.);
double b = a / (a/2.); // Both operator/ should be called. I would expect b value to be 2.
```

Source code:

```
/* Curiously Recurring Template Pattern */
template <typename T, template<typename> class crtpType>
struct crtp
{
T& underlying() { return static_cast<T&>(*this); }
T const& underlying() const { return static_cast<T const&>(*this); }
};
/* Inheriting class can be divided by a scalar */
template<typename T>
struct Divable : crtp<T, Divable>
{
T operator/(double const& scalar) const { return T(this->underlying().get() / scalar); }
};
/* Inheriting class can be divided by itself */
template<typename T>
struct Ratioable : crtp<T, Ratioable>
{
double operator/(T const& other) const { return this->underlying().get() / other.get(); }
};
struct DoubleWrapper :
public Divable<DoubleWrapper>,
public Ratioable<DoubleWrapper>
{
explicit DoubleWrapper(double val) : val_(val) {}
double get() const { return val_; }
private:
double val_;
};
```