Since go
is a dependent name of a template, you need to use the template
disambiguator:
case a: return &FunctionWrapper<a>::template go<T>;
// ^^^^^^^^
case b: return &FunctionWrapper<b>::template go<T>;
// ^^^^^^^^
This tells the compiler to parse what follows the scope resolution operator (::
) as the name of a template, and the subsequent angular brackets as delimiters for the template arguments.
Why is this failing to build under GCC, and how do I fix it?
Because GCC is conforming to the Standard, and performs two-phase name lookup, while MSVC delays name lookup until instantiation time and, therefore, knows that go
is the name of a template.
Before instantiation this information is not available, because it is impossible to know what T
is, and the primary template could be specialized for a given T
so that go
is not the name of a member function template, but rather of a data member.
This said, I expect MSVC to support the template
disambiguator anyway, so adding it should make your program compile both on GCC/Clang/whatever-conforms-to-the-Standard and on MSVC.