Шаблон функции с неиспользуемым параметром шаблона

template<typename T>
struct a 
{ 
  using type = int;
  typename T::type i;
};

template<typename T, typename = a<T>>
void f1(T) {}

template<typename T, typename = typename a<T>::type>
void f2(T) {}

int main()
{
  f1<int>(1); // ok
  f2<int>(1); // error

  return 0;
}

Экземпляр a<int> должно быть ошибка, потому что int::type незаконно Но похоже что f1<int> не может вызвать создание экземпляров a<T>, но f2<int> Можно. В чем причина?

1 ответ

Решение

Когда тип используется в качестве аргумента шаблона (включая аргумент шаблона по умолчанию), необязательно указывать полный тип.

Аргумент шаблона для параметра шаблона типа должен быть идентификатором типа, который может называть неполный тип:

Таким образом, для f1, аргумент шаблона по умолчанию a<T> и это не должно быть полным. Дано f1<int>(1);a<int> не нужно создавать экземпляры.

Но когда вы ссылаетесь на член шаблона класса, в качестве аргумента шаблона по умолчанию typename a<T>::type из f2, a<T> должен быть завершенным типом, а затем вызывать неявную реализацию.

Когда код ссылается на шаблон в контексте, который требует полностью определенного типа, или когда полнота типа влияет на код, и этот конкретный тип не был явно создан, происходит неявная реализация. Например, когда создается объект этого типа, но не когда создается указатель на этот тип.

Это относится к элементам шаблона класса: если этот элемент не используется в программе, он не создается и не требует определения.

Так дано f2<int>(1);, a<int> будет создан, а затем вызовет ошибку компиляции.

Другие вопросы по тегам