https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77660

            Bug ID: 77660
           Summary: Conversion operator unknown or ambiguous: gcc or clang
                    behave differently
           Product: gcc
           Version: 5.4.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: naupacte at sfr dot fr
  Target Milestone: ---

In relation with bug #50306:
(using gcc5.4.1 or gcc6.1 from macports)

struct A;
struct B;

template <class T> struct Ptr
{
        template <class U> operator const Ptr<U>& () const;
#ifdef GCC_BUT_CLANG_DECLARES_IT_IS_AMBIGUOUS
        template <class U> operator       Ptr<U>  () const; // required by gcc
but skipped for clang
#endif
};


const Ptr<A>& foo1 (const Ptr<B>& b) { return b;}//gcc ok 
      Ptr<A>  foo2 (const Ptr<B>& b) { return b;}// needs
GCC_BUT_CLANG_DECLARES_IT_IS_AMBIGUOUS to be set
      Ptr<A>  foo2a(const Ptr<B>& b) { return static_cast<Ptr<A>>(b);} //gcc
patch


Who is right? Gcc cannot convert from const Ptr<B>& to Ptr<A> via const
Ptr<A>&. I guess it has an influence on its inability to get the common type
for brace-lists or ?: pairs when only the reference conversion is given.

To avoid error: define GCC_BUT_CLANG_DECLARES_IT_IS_AMBIGUOUS only for gcc.
Otherwise, we get:

GCC
====
/opt/local/bin/gcc-mp-6 -x c++ -std=c++1y -c program.cpp

program.cpp: In function 'Ptr<A> foo2(const Ptr<B>&)':
program.cpp:22:47: error: could not convert 'b' from 'const Ptr<B>' to 'Ptr<A>'
       Ptr<A>  foo2 (const Ptr<B>& b) { return b;}// needs
GCC_BUT_CLANG_DECLARES_IT_IS_AMBIGUOUS to be set

CLANG
=====

clang-mp-3.8 -x c++ -std=c++1y -c program.cpp
-DGCC_BUT_CLANG_DECLARES_IT_IS_AMBIGUOUS

program.cpp:22:47: error: conversion from 'const Ptr<B>' to 'Ptr<A>' is
ambiguous
      Ptr<A>  foo2 (const Ptr<B>& b) { return b;}// needs
GCC_BUT_CLANG_DECLARES_IT_IS_AMBIGUOUS to be set
                                              ^
program.cpp:13:76: note: candidate function [with U = A]
        template <class U> operator const Ptr<U>& () const;
                           ^
program.cpp:15:76: note: candidate function [with U = A]
        template <class U> operator       Ptr<U>  () const;
                           ^
program.cpp:23:47: error: ambiguous conversion for static_cast from 'const
Ptr<B>' to 'Ptr<A>'
      Ptr<A>  foo2a(const Ptr<B>& b) { return static_cast<Ptr<A>>(b);} //gcc
patch
                                              ^~~~~~~~~~~~~~~~~~~~~~
program.cpp:11:27: note: candidate is the implicit copy constructor
template <class T> struct Ptr
                          ^
program.cpp:11:27: note: candidate is the implicit move constructor
2 errors generated.

Reply via email to