Disambiguation in Multiple Inheritance with Overlapping Types
Multiple inheritance can lead to ambiguous class-member calls when different base classes have non-overlapping sets of applicable types for polymorphic methods. Consider the scenario where a variadic base class template, Base, defines a method, foo(), which can only be invoked with template parameters contained within its type parameter pack.
In our example:
<code class="cpp">template <typename ... Types> class Base { public: template <typename T> typename std::enable_if<Contains<T, Types ...>::value>::type foo() { std::cout << "Base::foo()\n"; } };
We can derive a class, Derived, that inherits twice from Base with non-overlapping type sets:
<code class="cpp">struct Derived: public Base<int, char>, public Base<double, void> {};</code>
When calling Derived().foo
Why the Compiler Can't Resolve the Ambiguity
The merge rules for class-member lookup state that if the declaration set of the derived class (in this case, Derived) is empty, the lookup set for a member (in this case, foo) is merged from all direct base classes. However, since our base classes have differing declaration sets for foo, the merge is ambiguous.
Workarounds
To resolve the ambiguity, we can make the declaration set of Derived non-empty by adding using declarations for the foo methods in the bases:
<code class="cpp">struct Derived: public Base<int, char>, public Base<double, void> { using Base<int, char>::foo; using Base<double, void>::foo; };</code>
Using declarations bring members from base classes into the derived class, effectively providing Derived with two overloads of foo. The compiler can then unambiguously call the appropriate overload.
Alternative Solutions
The above is the detailed content of How to Resolve Ambiguity in Multiple Inheritance with Overlapping Types When Calling Polymorphic Methods?. For more information, please follow other related articles on the PHP Chinese website!