Проблема в том, что когда компилятор встречает Op.Execute<char>();
и пытается его проанализировать, он запутывается.
Op
является зависимым именем, поэтому компилятор мало что знает о его членах. Так что он не знает, что Execute
является функцией шаблона. Вместо этого предполагается, что <
означает меньше, чем.
Вы пытаетесь сравнить какого-то неизвестного члена Execute
с чем-то другим.
Таким образом, строка должна выглядеть следующим образом:
case 1: return Op.template Execute<char>();
Теперь компилятор знает, что Execute
- это шаблон, поэтому, когда он встречает <
, он не «меньше чем», а начало параметров шаблона.
Проблема аналогична необходимости typename
при указании типов, принадлежащих зависимому имени. Когда вы ссылаетесь на функцию-член шаблона и аргументы шаблона задаются явно, вам необходимо ключевое слово template
.
GCC ведет себя правильно, а MSVC слишком мягок. Если вы добавите ключевое слово template
, ваш код будет работать в обоих компиляторах (и будет корректным в соответствии со стандартом)