Home  >  Article  >  Backend Development  >  How to Resolve Ambiguity in Multiple Inheritance with Overlapping Types When Calling Polymorphic Methods?

How to Resolve Ambiguity in Multiple Inheritance with Overlapping Types When Calling Polymorphic Methods?

Linda Hamilton
Linda HamiltonOriginal
2024-10-25 06:23:02260browse

How to Resolve Ambiguity in Multiple Inheritance with Overlapping Types When Calling Polymorphic Methods?

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(), the compiler cannot resolve which base-class to invoke foo() from, leading to an ambiguous call error.

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

  • Base Collector Class: This class template can collect using declarations for multiple bases, reducing the need for explicit declarations.
  • Pack Expansion in C 17: Pack expansion can be used to simplify the BaseCollector template to a single line, making it more concise and efficient to compile.

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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn