Home >Backend Development >C++ >Why Does Multiple Inheritance Ambiguity Occur in C When Calling a Variadic Template Member Function?
Disambiguating Multiple Inheritance Class Members
Consider the following variadic base class template:
<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"; } };
The foo() member can only be called with a template parameter matching one of the types in the Types pack. Now, let's define a derived class with non-overlapping base types:
<code class="cpp">struct Derived : public Base<int, char>, public Base<double, void> {};</code>
Calling Derived().foo
Why the Compiler Cannot Resolve the Ambiguity:
The merge rules for member lookup [class.member.lookup] state that when the derived class has an empty declaration set (no members), the lookup sets from all base classes must be merged. In our case, the base classes have differing declaration sets, so the merge fails.
Solutions:
To avoid this ambiguity, we can add using declarations to the derived class:
<code class="cpp">struct Derived : public Base<int, char>, public Base<double, void> { using Base<int, char>::foo; using Base<double, void>::foo; };</code>
By introducing overloads of foo in the derived class, we effectively bypass the merge rules.
Using a Collector Class:
Alternatively, we can use a template class to aggregate the using declarations from all base classes:
<code class="cpp">template <typename... Bases> struct BaseCollector; template <typename Base, typename... Bases> struct BaseCollector<Base, Bases...> : Base, BaseCollector<Bases...> { using Base::foo; using BaseCollector<Bases...>::foo; }; struct Derived : BaseCollector<Base2<int>, Base2<std::string>> {};</code>
This approach is more efficient to compile in C 17, as it allows pack expansion of using declarations.
The above is the detailed content of Why Does Multiple Inheritance Ambiguity Occur in C When Calling a Variadic Template Member Function?. For more information, please follow other related articles on the PHP Chinese website!