Basically I want to have multiple member functions with same name, but different signature, spread in multiple base classes.
Example:
#include <iostream>
struct A
{
void print(int) { std::cout << "Got an int!" << std::endl; }
};
struct B
{
void print(double) { std::cout << "Got a double!" << std::endl; }
};
struct C : A, B {};
int main()
{
C c;
c.print((int)0);
return 0;
};
But I got this error on clang:
main.cpp:18:7: error: member 'print' found in multiple base classes of different types
c.print((int)0);
^
main.cpp:5:10: note: member found by ambiguous name lookup
void print(int) { std::cout << "Got an int!" << std::endl; }
^
main.cpp:10:10: note: member found by ambiguous name lookup
void print(double) { std::cout << "Got a double!" << std::endl; }
Why is it ambiguous? Even with different number of arguments I get the same error.
Is there any workaround to get similar behavior?
Operator overloading of member function When overloading an operator using a member function: The overloaded operator must be added as a member function of the left operand. The left operand becomes the implicit *this object. All other operands become function parameters.
You can derive a class from any number of base classes. Deriving a class from more than one direct base class is called multiple inheritance. The order of derivation is relevant only to determine the order of default initialization by constructors and cleanup by destructors.
C++ lets you specify more than one function of the same name in the same scope. These functions are called overloaded functions, or overloads. Overloaded functions enable you to supply different semantics for a function, depending on the types and number of its arguments.
But C# does not support multiple class inheritance. To overcome this problem we use interfaces to achieve multiple class inheritance. With the help of the interface, class C( as shown in the above diagram) can get the features of class A and B.
Use a using
declaration in the derived class - it will fix your issues. It makes both overloads visible and viable to participate in the resolution.
struct C : A, B {
using A::print;
using B::print;
};
To answer why this is ambiguous: it is actually not about visibility, but about the inability to participate in the overload resolution, due to not being defined in the same scope. The using
declaration pulls those methods in the C
scope, so both of them become valid overloading resolution options.
Thanks to @Pete Becker for participating in this answer and pretty much creating this paragraph.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With