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
  }
```

Reply via email to