4

Why are the function calls to waitForEvent in main below ambiguous?

#include <iostream>
struct Event1 { char c1[1]; };
struct Event2 { char c2[2]; };

template<class Event> struct EventSource
{    
    void waitForEvent(Event e) { std::cout << sizeof(e) << "\n"; };
};

typedef EventSource<Event1> Event1Source;
typedef EventSource<Event2> Event2Source;

struct Event12Source : public Event1Source, public Event2Source {};

int main()
{
    Event12Source source;

    source.waitForEvent(Event1());
    source.waitForEvent(Event2());

    return 0;
}

Compiling it I get the following errors:

user@AHERLADUSERVM2:~/test/TemplateMultipleMethodInheritance$ g++ test.cpp  test.cpp: In function ‘int main()’: test.cpp:19:12: error: request for member ‘waitForEvent’ is ambiguous
     source.waitForEvent(Event1());
            ^ test.cpp:7:10: note: candidates are: void EventSource<Event>::waitForEvent(Event) [with Event = Event2]
     void waitForEvent(Event e) { std::cout << sizeof(e) << "\n"; };
          ^ test.cpp:7:10: note:                 void EventSource<Event>::waitForEvent(Event) [with Event = Event1] test.cpp:20:12: error: request for member ‘waitForEvent’ is ambiguous
     source.waitForEvent(Event2());
            ^ test.cpp:7:10: note: candidates are: void EventSource<Event>::waitForEvent(Event) [with Event = Event2]
     void waitForEvent(Event e) { std::cout << sizeof(e) << "\n"; };
          ^ test.cpp:7:10: note:                 void EventSource<Event>::waitForEvent(Event) [with Event = Event1]

(Why) is this not a simple case of function overloading resolution?

Thanks, Damian

Damian Birchler
  • 285
  • 1
  • 7
  • 2
    Add `using Event1Source::waitForEvent; using Event2Source::waitForEvent;` to the body of your derived class – Piotr Skotnicki Feb 10 '16 at 10:55
  • Thanks, @PiotrSkotnicki, now it works. Could you explain to me why these are needed? – Damian Birchler Feb 10 '16 at 10:59
  • @DamianBirchler Because `Event2Source` is later in the inheritance order, and, like any inherited class, it hides functions with the same name that come before it in the inheritance order. Doing what Piotr suggested tells the compiler to whip out all the other overloads from the specified class into the current class, thereby canceling the auto-hiding. – Yam Marcovic Feb 10 '16 at 12:50
  • Please see this [answer ](http://stackoverflow.com/questions/1313063/request-for-member-is-ambiguous-in-g) – Praveen Feb 10 '16 at 12:51

2 Answers2

1

This may not be what you want, but it will solve the ambiguity

source.EventSource<Event1>::waitForEvent(Event1());
source.EventSource<Event2>::waitForEvent(Event2());

Also, if you are ever tempted to add a base class to Event1 and Event2, be aware of this

AlwaysTraining
  • 2,039
  • 18
  • 12
-1

Because overloading does not work with inheritance. The derived class inherited the same function from two base classes which ambiguous.

kiran
  • 37
  • 5