Компилятор должен проверить, что то, что передается в шаблон, соответствует ожидаемому параметру шаблона. Теперь подумайте, я должен был написать это на вашем примере, где вы не видите foo
:
foo<C> f;
Это экземпляр CTAD или я передаю сам шаблон? Поскольку уже можно передавать шаблоны в качестве аргументов другим шаблонам.
template< template<typename> class T > struct foo {};
Если в этом контексте разрешить использование CTAD, то использование C
будет зависеть от контекста. Напротив, имя шаблона не имеет другого использования при объявлении переменной. Нет никакой двусмысленности при написании ...
C c;
... это может означать что-то отличное от CTAD, поэтому здесь это разрешено. Но контекст имеет значение, когда имя шаблона используется в качестве аргумента шаблона. В C ++ уже есть много контекстно-зависимых конструкций, поэтому добавление большего количества обычно плохая идея.