Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are two using clauses resolving to the same type seen as ambigious in gcc

I have two base classes with using clauses

 class MultiCmdQueueCallback {   using NetworkPacket  = Networking::NetworkPacket;   ....  }    class PlcMsgFactoryImplCallback {    using NetworkPacket = Networking::NetworkPacket;   ....  } 

I then declare a class

class PlcNetwork :    public RouterCallback,    public PlcMsgFactoryImplCallback,    public MultiCmdQueueCallback {   private:     void sendNetworkPacket(const NetworkPacket &pdu); } 

the compiler then flags an error reference to 'NetworkPacket' is ambiguous 'sendNetworkPacket(NetworkPacket &... '

Now both 'using clauses' resolve to the same underlying class Networking:NetworkPacket

and in fact if I replace the method declaration with:

 void sendNetworkPacket(const Networking::NetworkPacket &pdu); 

it compiles fine.

Why is the compiler treating each using clause as a distinct type even though they both point to the same underlying type. Is this mandated by the standard or do we have a compiler bug ?

like image 732
Andrew Goedhart Avatar asked Feb 12 '20 09:02

Andrew Goedhart


2 Answers

Before looking at alias resulting type, (and accessibility)

we look at names

and indeed,

NetworkPacket might be

  • MultiCmdQueueCallback::NetworkPacket
  • or PlcMsgFactoryImplCallback::NetworkPacket

The fact they both point to Networking::NetworkPacket is irrelevant.

We do first name resolution, which results in ambiguity.

like image 99
Jarod42 Avatar answered Oct 13 '22 05:10

Jarod42


You simply can resolve the ambiguity by manually selecting which one you want to use.

class PlcNetwork :    public RouterCallback,    public PlcMsgFactoryImplCallback,    public MultiCmdQueueCallback {  using NetworkPacket= PlcMsgFactoryImplCallback::NetworkPacket; // <<< add this line private:     void sendNetworkPacket(const NetworkPacket &pdu);  } 

The compiler only looks for the definitions in the base classes. If the same type and or alias is present in both base classes it simply complains that it does not know which one to use. It doesn't matter if the resulting type is the same or not.

The compiler only looks for names in the first step, fully independent if this name is a function, type, alias, method or whatever. If names are ambiguous no further action is done from the compiler! It simply complains with the error message and stops. So simply resolve the ambiguity with the given using statement.

like image 42
Klaus Avatar answered Oct 13 '22 05:10

Klaus