Reputation: 1999
I have a structure like this, with struct Baz inheriting from 2 different structs, Foo and Bar.
I have 2 methods called the same thing, one with a parameter of Foo and one with a parameter of Baz.
struct Foo
{
};
struct Bar
{
};
struct Baz : Foo, Bar
{
virtual void something(const Foo& foo)
{
};
virtual void something(const Bar& bar)
{
};
};
I call it like this
Baz baz;
baz.something(baz);
And understandably I have an issue with my code knowing which function I am calling if I pass it an instance of Baz. I get “Ambiguous call to overloaded function”.
I know I can cast my Baz to Foo or Bar to resolve the issue...
Baz baz;
baz.something((Bar)baz);
...but is there another way of dealing with this design issue?
I want to call the Foo method ONLY if the object being passed is not of type Bar.
edit:
If this was C# (which it isn't) I could probably solve this using a template where clause.
Upvotes: 1
Views: 995
Reputation: 171117
First off, note that the cast you've used would create a temporary object. You probably meant this:
baz.something(static_cast<Bar&>(baz));
And to answer your question, it should be possible to use SFINAE for this:
struct Baz : Foo, Bar
{
virtual void something(const Bar &bar)
{ /* ... */ }
template <
class T,
class = typename std::enable_if<
std::is_convertible<const T&, const Foo&>::value &&
!std::is_convertible<const T&, const Bar&>::value
>::type
>
void something (const T &foo)
{ something_impl(static_cast<const Foo&>(foo)); }
private:
virtual void something_impl(const Foo &foo)
{ /* ... */ }
};
Upvotes: 2