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

            Bug ID: 83145
           Summary: Ambiguous overload with templates, only GCC7 C++17
                    mode (regression?)
           Product: gcc
           Version: 7.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: l.lunak at centrum dot cz
  Target Milestone: ---

The following code produces an ambiguous overload error only with GCC7 in C++17
mode. GCC6 is fine, GCC7 in C++14 mode is fine, Clang5 is fine, MSVC2015/2017
are fine. It would seem to me that the first overload is more specific and thus
should be the one selected.

======
template <typename... TValues>
class Variant {
};

class BinaryOutputStream {
};

template <typename... TValues>
BinaryOutputStream& operator<<(BinaryOutputStream& stream, const
Variant<TValues...>& /*variant*/) {
    return stream;
}

template <template <typename T, typename TAllocator, typename TCounter> class
TCollection,
          typename T,
          typename TAllocator,
          typename TCounter>
BinaryOutputStream& operator<<(BinaryOutputStream& ostream, const
TCollection<T, TAllocator, TCounter>& /*arr*/) {
    return ostream;
}

int main()
    {
    Variant<float, int, char> variant;
    BinaryOutputStream stream;
    stream << variant;
    return 0;
    }
=====

$ g++-7 -Wall -Wextra a.cpp -c -std=gnu++17
a.cpp: In function ‘int main()’:
a.cpp:25:12: error: ambiguous overload for ‘operator<<’ (operand types are
‘BinaryOutputStream’ and ‘Variant<float, int, char>’)
     stream << variant;
     ~~~~~~~^~~~~~~~~~
a.cpp:9:21: note: candidate: BinaryOutputStream&
operator<<(BinaryOutputStream&, const Variant<TValues ...>&) [with TValues =
{float, int, char}]
 BinaryOutputStream& operator<<(BinaryOutputStream& stream, const
Variant<TValues...>& /*variant*/) {
                     ^~~~~~~~
a.cpp:17:21: note: candidate: BinaryOutputStream&
operator<<(BinaryOutputStream&, const TCollection<T, TAllocator, TCounter>&)
[with TCollection = Variant; T = float; TAllocator = int; TCounter = char]
 BinaryOutputStream& operator<<(BinaryOutputStream& ostream, const
TCollection<T, TAllocator, TCounter>& /*arr*/) {
                     ^~~~~~~~
$ g++-7 -Wall -Wextra a.cpp -c -std=gnu++14
$ g++-6 -Wall -Wextra a.cpp -c -std=gnu++17
$ clang++ -Wall -Wextra a.cpp -c -std=gnu++17
$ g++-7 -v
Using built-in specs.
COLLECT_GCC=g++-7
COLLECT_LTO_WRAPPER=/usr/lib64/gcc/x86_64-suse-linux/7/lto-wrapper
OFFLOAD_TARGET_NAMES=hsa:nvptx-none
Target: x86_64-suse-linux
Configured with: ../configure --prefix=/usr --infodir=/usr/share/info
--mandir=/usr/share/man --libdir=/usr/lib64 --libexecdir=/usr/lib64
--enable-languages=c,c++,fortran,ada,go
--enable-offload-targets=hsa,nvptx-none=/usr/nvptx-none, --without-cuda-driver
--enable-checking=release --disable-werror
--with-gxx-include-dir=/usr/include/c++/7 --enable-ssp --disable-libssp
--disable-libvtv --disable-libcc1 --disable-plugin
--with-bugurl=http://bugs.opensuse.org/ --with-pkgversion='SUSE Linux'
--with-slibdir=/lib64 --with-system-zlib --enable-__cxa_atexit
--enable-libstdcxx-allocator=new --disable-libstdcxx-pch
--with-default-libstdcxx-abi=gcc4-compatible
--enable-version-specific-runtime-libs --with-gcc-major-version-only
--enable-linker-build-id --enable-linux-futex --enable-gnu-indirect-function
--program-suffix=-7 --without-system-libunwind --enable-multilib
--with-arch-32=x86-64 --with-tune=generic --build=x86_64-suse-linux
--host=x86_64-suse-linux
Thread model: posix
gcc version 7.1.1 20170607 [gcc-7-branch revision 248970] (SUSE Linux)

Reply via email to