Это просто вопрос подписи.В основном вы передаете неправильный тип.
И A a
, и A<> a
означают, что вам нужен экземпляр A
со значением параметра шаблона по умолчанию, то есть вы получите A< void >
.
Функция g< C >()
принимает параметр шаблона, который является типом, а не другим шаблонным типом.Когда вы вызываете его с помощью A<>
, вы сообщаете компилятору, что вы хотите использовать «экземпляр» шаблонного типа A
, который действителен.Когда вы вызываете его с помощью A
, вы сообщаете компилятору, что хотите вызвать g< C >()
, причем C
является шаблонным типом, который не соответствует его сигнатуре.
Если вы объявляете / определяете g()
следующим образомtemplate <typename <typename> TTemplatedType> g()
он будет принимать вызов таким образом g< A >()
, но g< A<> >()
потерпит неудачу, потому что теперь он больше не хочет чего-то другого, кроме шаблонного типа.