https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106046
Bug ID: 106046 Summary: GCC fails to disambiguate call to static member function when inside a class template Product: gcc Version: 11.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: jlame646 at gmail dot com Target Milestone: --- The following example fails to compile with gcc 11.2 while it works with other compilers like clang and msvc. This can be verified here:https://godbolt.org/z/oK3xxTT14 The example is as follows: ``` #include <utility> #include <type_traits> template<class F> concept NodeFunctionType = std::invocable<std::remove_reference_t<F>, int>; template<class T> concept ExtracterType = requires { typename T::I_am_an_extracter; }; template<class T = int> struct NodeMaker { template<class... Args> static constexpr auto create_node(Args&&... args) { return new T(std::forward<Args>(args)...); } template<NodeFunctionType DataMaker> requires (!ExtracterType<DataMaker>) static constexpr auto create_node(DataMaker&& data_maker) { return create_node(); } // line 13 template<ExtracterType DataMaker> requires (!NodeFunctionType<DataMaker>) static constexpr auto create_node(DataMaker&& data_maker) { return create_node(); } // line 16 void do_something() { const auto target = create_node(0); //this does not work in gcc } }; int main() { const auto target = NodeMaker<>::create_node(0); //but this works } ``` I have placed comments in the above example so that it will be easier to see where the problem is. As can be seen in the above example, the issue is with the call `create_node(0)` from inside `do_something`. Moreover i noticed that we can resolve this issue by explicitly qualifying the call with `NodeMaker<>::` as shown below: ``` void do_something() { //----------------------vvvvvvvvvvvvv--------------->added this qualification const auto target = NodeMaker<>::create_node(0); //works now in gcc } ``` After explicitly qualification the program works. Demo: https://godbolt.org/z/oMddPGj6x Additionally, note that if we use `NodeMaker<T>::` instead of `NodeMaker<>::` then the issue will reappear. Demo: https://godbolt.org/z/xfK1nG9s5 ``` void do_something() { const auto target = NodeMaker<T>::create_node(0); //this does not work in gcc } ```