http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53606
Bug #: 53606 Summary: Invalid candidate chosen; warning message claims to know better than the Standard Classification: Unclassified Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassig...@gcc.gnu.org ReportedBy: hst...@ca.ibm.com Host: powerpc64-unknown-linux-gnu Target: powerpc64-unknown-linux-gnu GCC emits a warning stating that the template-dependent call in the type of a parameter of a function template instantiation is ambiguous according to the Standard. It then fails to remove the candidate despite what should then be substitution failure. I am not quite sure how GCC found one of the operator+ overloads to be better than the other, but whatever mechanism is being used, it should not interfere with the translation of a well-formed program. ### Self-contained source (op_overload_sfinae.cpp):> cat op_overload_sfinae.cpp template <typename T> struct false_ { enum : bool { value = false }; }; struct A { template <typename T> int operator +(const T &) const; }; template <typename T> int operator +(const A &, const T &); const int &lv_const_int(); template <typename T> T &lv_T(); template <typename T> void foo(void *, char * = 0) { } template <typename T> void foo(int, char (*)[sizeof (lv_T<T>() + lv_const_int(), 0)] = 0) { static_assert(false_<T>::value, "If the warning is correct, then the Standard says I should not see this."); } int main() { foo<A>(0); } ### Compiler invocation: g++-4.7.0 -c op_overload_sfinae.cpp -std=c++11 ### Compiler output: op_overload_sfinae.cpp: In instantiation of 'void foo(int, char (*)[sizeof (((lv_T<T>() + lv_const_int()), 0))]) [with T = A]': op_overload_sfinae.cpp:27:12: required from here op_overload_sfinae.cpp:21:66: warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second: [enabled by default] op_overload_sfinae.cpp:10:5: note: candidate 1: int operator+(const A&, const T&) [with T = int] op_overload_sfinae.cpp:6:5: note: candidate 2: int A::operator+(const T&) const [with T = int] op_overload_sfinae.cpp:22:4: error: static assertion failed: If the warning is correct, then the Standard says I should not see this. ### g++ -v output:> g++-4.7.0 -v Using built-in specs. COLLECT_GCC=g++-4.7.0 COLLECT_LTO_WRAPPER=/data/gcc/libexec/gcc/powerpc64-unknown-linux-gnu/4.7.0/lto-wrapper Target: powerpc64-unknown-linux-gnu Configured with: ../gcc-4.7.0/configure --prefix=/data/gcc --program-suffix=-4.7.0 --disable-libssp --disable-libgcj --enable-version-specific-runtime-libs --with-cpu=default32 --enable-secureplt --with-long-double-128 -- enable-shared --enable-__cxa_atexit --enable-threads=posix --enable-languages=c,c++,fortran --with-mpfr=/usr/local/ --with-mpc=/usr/local/ --with-gmp=/usr/local/ Thread model: posix gcc version 4.7.0 (GCC)