From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12349 invoked by alias); 17 Feb 2011 13:16:29 -0000 Received: (qmail 12337 invoked by uid 22791); 17 Feb 2011 13:16:27 -0000 X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=AWL,BAYES_00,FREEMAIL_FROM,RCVD_IN_DNSWL_NONE,T_TO_NO_BRKTS_FREEMAIL X-Spam-Check-By: sourceware.org Received: from mailout-de.gmx.net (HELO mailout-de.gmx.net) (213.165.64.23) by sourceware.org (qpsmtpd/0.43rc1) with SMTP; Thu, 17 Feb 2011 13:16:22 +0000 Received: (qmail invoked by alias); 17 Feb 2011 13:16:19 -0000 Received: from LN-mac29.grenoble.cnrs.fr (EHLO axel) [147.173.67.29] by mail.gmx.net (mp015) with SMTP; 17 Feb 2011 14:16:19 +0100 Date: Thu, 17 Feb 2011 14:05:00 -0000 From: Axel Freyn To: gcc-help@gcc.gnu.org Subject: Re: Strange behavior with templates and G++ Message-ID: <20110217131616.GU5274@axel> Mail-Followup-To: gcc-help@gcc.gnu.org References: <201102171203.53710.pascal@francq.info> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Mutt/1.5.18 (2008-05-17) X-IsSubscribed: yes Mailing-List: contact gcc-help-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-help-owner@gcc.gnu.org X-SW-Source: 2011-02/txt/msg00259.txt.bz2 On Thu, Feb 17, 2011 at 12:22:53PM +0000, Jonathan Wakely wrote: > [Moved from the gcc list] > > On 17 February 2011 11:03, Pascal Francq wrote: > > Hi, > > While compiling the following code, I got an error : > > > > > > template class Super > > { > > public: > >        Super(void) {} > >        void Test(C*) {} > > }; > > > > class A > > { > > public: > >        A(void) {} > > }; > > > > class A1 : public A > > { > > public: > >        A1(void) : A() {} > > }; > > > > class A2 : public A > > { > > public: > >        A2(void) : A() {} > > }; > > > > class Super2 : public Super, public Super > > { > > public: > >        Super2(void) {} > > }; > > > > void Test(void) > > { > >        Super2 T; > >        A1* ptr; > >        T.Test(ptr); > > } > > > > > > The compiler gives me the following error for the Test() function: > >        error: request for member ‘Test’ is ambiguous > >        error: candidates are:  void Super::Test(C*) [with C = A2] > >        error:                          void Super::Test(C*) [with C = A1] > > But here the call refers clearly to the second method. The error still appears > > if A1 and A2 do not inherit from a same root class. If I replace the code with > > an explicit call it works: > >        T.Super::Test(ptr) > > But this make the code less cleaner. > > > > Is this a problem related to a misunderstood concept from me, a wrong > > implementation or a technical problem of g++ ? > > > The ambiguity has nothing to do with templates, the code can be reduced to: > > class A1 > { > public: > void Test(A1*) {} > }; > > class A2 > { > public: > void Test(A2*) {} > }; > > class Super2 : public A1, public A2 > { > }; > > void Test(void) > { > Super2 T; > A1* ptr; > T.Test(ptr); > } > > This is covered by 10.2 [class.member.lookup] in the C++ standard, > which says that a name is ambiguous if found in more than one base > class. That makes the lookup ill-formed, before overload resolution > is attempted. In addition: it is not necessary to use everywhere an explicit call. You can import the function by adding "using"-definitions. With: class Super2 : public A1, public A2 { public: using A1::Test; using A2::Test; }; you can call T.Test(ptr) directly, and C++ will do correct overload resolution -- both with and without templates HTH, Axel