https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101698
Bug ID: 101698 Summary: Template type conversion operator from base class preferred over matching overload Product: gcc Version: 11.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: ammiera at hotmail dot com Target Milestone: --- There are two conversion operators, template and non-templated. Their return type might match: virtual operator const std::string&() const; template <class T> operator const T&() const; If so, when trying to call it, the template is always preferred over non-template and there's no way to SFINAE out of it: #include <iostream> #include <string> #include <type_traits> class Base { public: template <class T> operator const T&() const { std::cout << "use template method" << std::endl; static T tmp{}; return tmp; } virtual operator const std::string&() const { std::cout << "use overload method" << std::endl; const static std::string tmp; return tmp; } }; template <class T> class Derive : public Base { public: operator const T&() const override { using Y = std::string; static_assert(std::is_same<T, Y>::value, ""); std::string static res; res = Base::operator const Y&(); res = Base::operator const T&(); return res; } }; int main() { Derive<std::string> a; const std::string& b = a; (void)b; } Reproduced locally on: gcc (SUSE Linux) 11.1.1 20210721 [revision 076930b9690ac3564638636f6b13bbb6bc608aea] Copyright (C) 2021 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Did a quick bisection via godbolt.org, the last version it's didn't occur is 7.5. https://gcc.godbolt.org/z/KcbK9vv5z